Appending an icon to a table column in vuetify data table? - javascript

I have a Vuetify data table and I am trying to append an icon to just the <td> with protein in it but the way it is being rendered, I am not able to understand how would I go about it?
So I have component which is being imported into the Vuetify data table template and that component separately consists of the icon div.
<template>
<v-data-table>
<template v-slot:items="props">
<my-component
:protein="props.item.protein"
:carbs="props.item.carbs"
:fats = "props.item.fats"
:iron="props.item.iron"/>
</template>
<v-data-table>
</template>
And in my component i have the template setup like this:-
<template>
<tr>
<td>
<v-checkbox> </v-checkbox>
<td>
<div>
<router-link>
<i class="fa fa-globe"></i>
</router-link>
</div>
</tr>
</template>
Not sure how I can append the icon to the protein field?

If I understood your question correctly, you want dynamic icons for (or appended onto) the protein fields, so here's one way to achieve that:
Vue.component('MyComponent', {
template: `
<tr>
<td><i :class="['fa', 'fa-'.concat(protein)]"></i></td>
<td>{{carbs}}</td>
<td>{{fats}}</td>
<td>{{iron}}</td>
</tr>
`,
props: ['protein', 'carbs', 'fats', 'iron']
});
new Vue({
el: '#demo',
data: () => ({
opts: {
headers: [
{ text: 'Protein', value: 'protein' },
{ text: 'Carbs', value: 'carbs' },
{ text: 'Fats', value: 'fats' },
{ text: 'Iron', value: 'iron' }
],
items: [
{ protein: 'cutlery', carbs: 4, fats: 1, iron: 5 },
{ protein: 'shopping-basket', carbs: 5, fats: 5, iron: 0 },
{ protein: 'beer', carbs: 2, fats: 9, iron: 3 }
],
hideActions: true
}
})
})
<link href="http://netdna.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" />
<link href="https://fonts.googleapis.com/css?family=Roboto:400,500,700|Material+Icons" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify#1.x/dist/vuetify.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/vue#2.x/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify#1.x/dist/vuetify.js"></script>
<div id="demo">
<v-data-table v-bind="opts">
<template #items="{ item }">
<my-component v-bind="item"></my-component>
</template>
</v-data-table>
</div>

Hope this helps someone.
<template>
<v-data-table>
<template v-slot:item.protein="{ item }">
<i class="fa fa-globe"></i>{{ item.protein }}
</template>
</v-data-table>
</template>

Related

How to add a tooltip to a single header from a list of headers in Vue?

I am trying to create a tooltip for only a single header (the one with the value 'Retire') but for none of the other headers.
This has been a long journey. I am new with Vue and thus have allied with the AI species (chatgpt) which has helped me somewhat. Now I am at the point where my front shows no errors, the browser shows no errors but no tooltip is shown. Can anyone help me achieve this? Thanks
This is the snippet of code where I am creating the data table and setting the headers as it looks at the moment.
<v-data-table
class="zebrastripes"
:items="autofilterItems"
:items-per-page="20"
:footer-props="{
'items-per-page-options': [5, 10, 20, -1],
}"
:headers="headers"
:search="search"
:no-results-text="$t('General.noSearchMatch')"
:custom-sort="dateSorting"
:loading="trigger_loader"
>
<template v-slot:header="header">
<th :key="header.text">
<v-tooltip :value="header.value === 'Retire'" bottom>
<template v-slot:activator="{ on }">
<span v-on="on">{{header.text}}</span>
</template>
<span v-if="header.value === 'Retire'">{{ header.tooltip }}</span>
</v-tooltip>
</th>
</template>
</v-data-table>
You can use header.value slot on each header item and apply a condition to show the tooltip only for specific headers.
Here is an example that is working with tooltips. You will see that the tooltip would only be displayed for a header with the title Retire.
<!DOCTYPE html>
<html>
<head>
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/#mdi/font#4.x/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.min.css" rel="stylesheet">
</head>
<body>
<div id="app">
<v-app>
<v-data-table
:headers="headers"
:items="autofilterItems"
:items-per-page="5"
class="elevation-1"
:items-per-page="20"
no-results-text="General.noSearchMatch"
>
<template v-for="header in headers" v-slot:[`header.${header.value}`]="{ header }">
<v-tooltip bottom v-if="header.value == 'Retire'">
<template v-slot:activator="{ on }">
<span v-on="on">{{ header.text }}</span>
</template>
<span>{{ header.tooltip }}</span>
</v-tooltip>
<span v-else>{{ header.text }}</span>
</template>
</v-data-table>
</v-app>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue#2.x/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/1.2.2/axios.min.js" integrity="sha512-QTnb9BQkG4fBYIt9JGvYmxPpd6TBeKp6lsUrtiVQsrJ9sb33Bn9s0wMQO9qVBFbPX3xHRAsBHvXlcsrnJjExjg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script>
new Vue({
el: '#app',
vuetify: new Vuetify(),
data() {
return {
headers: [
{
text: 'Retire',
value: 'Retire',
sortable: false,
tooltip: 'I am a tooltip'
},
{
text: 'Dessert (100g serving)',
value: 'name',
sortable: false,
},
{
text: 'Fat (g)',
value: 'fat',
sortable: false,
},
{
text: 'Carbs (g)',
value: 'carbs',
sortable: false,
},
{
text: 'Protein (g)',
value: 'protein',
sortable: false,
},
{
text: 'Iron (%)',
value: 'iron',
sortable: false,
},
],
autofilterItems: [{
name: 'Frozen Yogurt',
Retire: true,
fat: 6.0,
carbs: 24,
protein: 4.0,
iron: 1,
},
{
name: 'Ice cream sandwich',
Retire: true,
fat: 9.0,
carbs: 37,
protein: 4.3,
iron: 1,
},
],
}
},
})
</script>
</body>
</html>

The b-button is not displayed in the b-table VueJs

I'm starting at Vue Js, my problem is that my b-button is not shown in my table and I don't understand why.
Here is my HTML code:
<div id="listlocales">
<div class="overflow-auto">
<b-button size ="sm" href="{% url 'newLocal'}" variant="outline-primary"> Nuevo Local</b-button>
<br></br>
<b-table
id="my-table"
striped responsive="sm"
:items="items"
:fields="fields"
:per-page="recordsPerPage"
:current-page="currentPage">
<template #cell(actions)='data'>
<b-button size="sm" variant="primary" #click="getLocales()"> Editar </b-button>
<b-button size="sm" variant="danger" href="{% url 'newLocal' %}"> Eliminar </b-button>
</template>
</b-table>
<b-pagination
v-model="currentPage"
:total-rows="totalPages"
:per-page="recordsPerPage"
aria-controls="my-table"
></b-pagination>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue#2.5.21/dist/vue.js"></script>
<script src="//unpkg.com/bootstrap-vue#latest/dist/bootstrap-vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
And here is my script Vue code:
<script>
const listloc = new Vue({
el: '#listlocales',
data: {
items: [],
currentPage: 1,
totalPages: 0,
recordsPerPage: 10,
isLoading: false,
fields: [
{ key: 'id', label: 'ID' },
{ key: 'descripcion', label: 'Descripcion' },
{ key: 'clave', label: 'Clave' },
{ key: 'responsable', label: 'Responsable' },
{ key: 'actions', label: ''}
]
}, ...
});
</script>
</body>
</html>
I tried to use v-slot instead cell but isn't working anyway... Can someone help me for solving this issue.
The v-slot directive, that Boostrap is using, was introduced in Vue version 2.6.0. To fix your issue you have to upgrade your Vue version
<script src="https://cdn.jsdelivr.net/npm/vue#2.6.0/dist/vue.js"></script>

Show tooltip in Autocomplete dropdown items using Vuetify

I'm new to Vue.js and Vuetify
Problem - To show tooltip on each dropdown item in v-autocomplete
Solution - added v-tooltip component in item template
Code:
var app = new Vue({
el: "#app",
data: {
items: [{
value: 0,
text: "Matthews Webb"
},
{
value: 1,
text: "Teresa Ward"
},
{
value: 2,
text: "Cervantes Swanson"
},
{
value: 3,
text: "Helga Cooper"
},
{
value: 4,
text: "Solomon Jensen"
},
{
value: 5,
text: "Eliza Delgado"
},
{
value: 6,
text: "Dickson Parks"
},
{
value: 7,
text: "Etta Glenn"
},
{
value: 8,
text: "Alma Durham"
},
{
value: 9,
text: "Rosemary Conner"
}
],
selected: []
}
});
<link href="https://cdn.jsdelivr.net/npm/vuetify#1.x/dist/vuetify.min.css" rel="stylesheet" />
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify#1.x/dist/vuetify.js"></script>
<div id="app">
<v-app>
<v-content>
<v-container>
<v-autocomplete :items="items" v-model="selected" clearable multiple>
<template v-slot:item="data">
<v-tooltip right>
<template slot="activator" slot-scope="{ on }">
<v-list-tile-action>
<v-checkbox v-model="selected" :value="data.item.value"></v-checkbox>
</v-list-tile-action>
<v-list-tile-content>
<v-list-tile-title v-html="data.item.text" v-on="on"></v-list-tile-title>
</v-list-tile-content>
</template>
<span>{{ data.item.text }}</span>
</v-tooltip>
</template>
</v-autocomplete>
</v-container>
</v-content>
</v-app>
</div>
Problems after implementing the solutions:
Checkboxes are not clickable or item cannot be selected if clicked on the checkbox
On searching the item some of the checkboxes shows selected
Vue Version - 2.6.12
Vuetify Version - 1.5.24
Is there any other way to show tooltip on autocomplete dropdown items without disturbing the functionality or is there any mistake in my solution
Solution:
The v-input--selection-controls__ripple Div overlaps the input box of the selection control; hence binds to the click instead.
To fix this I applied a simple CSS Hack. Conceptually position it above by using position and z-index:-10 for the div.
that is illustrated with edits marked below as /* <--------------- */
<div class="v-input__slot">
<div class="v-input--selection-controls__input">
<input aria-checked="false" role="checkbox" type="checkbox" value="1" style="
position: relative; /* <--------------- */
">
<div class="v-input--selection-controls__ripple" style="
position: absolute; z-index: -10; /* <--------------- */
"></div>
<i aria-hidden="true" class="v-icon material-icons theme--light">check_box_outline_blank</i>
</div>
</div>

Vue updates all button text after changing specific button

Hi everyone I'm playing around with Vue JS but for some how I cannot get what I expected. Below are my code.
Template
<div id="app">
<v-app id="inspire">
<div class="text-xs-center" v-for="x in count" :key="x">
<v-menu offset-y>
<v-btn
slot="activator"
color="primary"
dark
>
{{name}}
</v-btn>
<v-list>
<v-list-tile
v-for="(item, index) in items"
:key="index"
#click="test(item.title)"
>
<v-list-tile-title>{{ item.title }}</v-list-tile-title>
</v-list-tile>
</v-list>
</v-menu>
</div>
</v-app>
</div>
Vue
new Vue({
el: '#app',
data: () => ({
name: 'default',
items: [
{ title: 'Click Me 1' },
{ title: 'Click Me 2' },
{ title: 'Click Me 3' },
{ title: 'Click Me 2' }
],
count: 10
}),
methods: {
test(title) {
this.name = title
}
}
})
What I want is that when I change a specific button text the other buttons should not be affected. But it seems my code is doing the opposite. What am I missing here? Any help, explanation would be much appreciated. Thanks
new Vue({
el: '#app',
data: () => ({
name: 'default',
items: [
{ title: 'Click Me 1' },
{ title: 'Click Me 2' },
{ title: 'Click Me 3' },
{ title: 'Click Me 2' }
],
count: 10
}),
methods: {
test(title) {
this.name = title
}
}
})
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify#1.5.3/dist/vuetify.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/vuetify#1.5.3/dist/vuetify.min.css">
<div id="app">
<v-app id="inspire">
<div class="text-xs-center" v-for="x in count" :key="x">
<v-menu offset-y>
<v-btn
slot="activator"
color="primary"
dark
>
{{name}}
</v-btn>
<v-list>
<v-list-tile
v-for="(item, index) in items"
:key="index"
#click="test(item.title)"
>
<v-list-tile-title>{{ item.title }}</v-list-tile-title>
</v-list-tile>
</v-list>
</v-menu>
</div>
</v-app>
</div>
You are iterating over a normal number, in your example 10, so you are just showing 10 times the same variable name.
If you now change that variable name to something, it will change in all the buttons accordingly.
You need some way to save the different names, e.g. an array of objects like your items with all the titles.
I took your code and changed it a bit. Instead of iterating over a fixed count, I created an array of names and iterate over that array. When you click one of the buttons and change the text, instead of just changing the universal name attribute - you change the name at the position in the array.
new Vue({
el: '#app',
data: () => ({
names: [
{name: 'default 1'}, {name: 'default 2'}, {name: 'default 3'}, {name: 'default 4'}],
items: [
{ title: 'Click Me 1' },
{ title: 'Click Me 2' },
{ title: 'Click Me 3' },
{ title: 'Click Me 4' }
],
}),
methods: {
test(title, index) {
this.names[index].name = title
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuetify/1.5.3/vuetify.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/vuetify/1.5.3/vuetify.css.map">
<div id="app">
<v-app id="inspire">
<div class="text-xs-center" v-for="(x, index) in names" :key="'name' + index">
<v-menu offset-y>
<v-btn
slot="activator"
color="primary"
dark
>
{{x.name}}
</v-btn>
<v-list>
<v-list-tile
v-for="(item, i) in items"
:key="'item' + i"
#click="test(item.title, index)"
>
<v-list-tile-title>{{ item.title }}</v-list-tile-title>
</v-list-tile>
</v-list>
</v-menu>
</div>
</v-app>
</div>

Vue Dynamic List

I'm creating a basic MTG Deckbuilder using Vue.Js. I'm trying to have the user type the card name into an input box then when the button is clicked, the deck list is update with the card name. Currently,the list add's a blank element for the card instead of the card name. Any ideas?
app.Vue:
<template>
<div id="app">
<deckBuilder #addCard="addCard" :title="title" :card="card" :deck="deck" />
</div>
</template>
<script>
import deckBuilder from './components/deckBuilder'
export default {
name: 'app',
components: {
deckBuilder,
},
data: () => ({
title: 'MTG Deck Builder',
card: {
name: '',
},
deck:[],
}),
methods: {
addCard: function(event,) {
this.deck.push(this.card.name);
},
},
}
</script>
deckBuilder.Vue:
<template>
<div>
<h1>{{ title }}</h1>
<input v-model="card.name" placeholder="Type a Card Name" />
<p> the card is: {{ card.name }}
<button #click="addCard">Add!</button>
<h2>Deck</h2>
<ul>
<li v-for="item in deck">{{ item.card }}</li>
</ul>
</div>
</template>
<script>
export default {
name: 'deckBuilder',
props: ['title', 'card', 'deck'],
methods: {
addCard() {
this.$emit('addCard')
}
},
}
</script>
Because you push string item instead of object
this.deck.push(this.card.name);
Correct template will be {{ item }}, not {{ item.card }}
This is because you are not emitting any data in your $emit
Try this,
In deckbuilder.vue
addCard() {
this.$emit('addCard',this.card.name);
}
In app.vue
addCard: function(cardName){
this.deck.push(cardName);
}
In html, v-for should be this way
<li v-for="item in deck">{{ item }}</li>
Try This
<!-- Menu Content -->
<ul class="nav-list" style="overflow: visible;">
<!-- Items -->
<span v-for="(menuItem, index) in menuItems" :key="index">
<li>
<nuxt-link :to="menuItem.link" :class="menuItem.class">
<i class="bx" :class="menuItem.icon || 'bx-square-rounded'" />
<!-- Link Name -->
<span class="links_name">{{ menuItem.name }}</span>
</nuxt-link>
</li>
</span>
</ul>
<script>
export default {
name: 'SidebarMenu',
menuItems: {
type: Array,
default: () => [
{
link: '/',
name: '_home',
icon: 'bx-home',
class: '',
},
{
link: '/blog',
name: '_blog',
icon: 'bx-edit',
class: '',
},
{
link: '/projects',
name: '_projects',
icon: 'bx-code',
class: ''
},
{
link: '/about',
name: '_about',
icon: 'bx-user',
class: ''
},
],
},
}
</script>

Categories

Resources