Merging multiple v-slot:activator and v-on in vuetify templates - vue.js

I'm trying to create reusable modal window that should be called by pressing on an icon on each of the v-data-table row. Besides, each icon should have a tooltip on mouse hover.
According to vuetify docs, both actions is using same constructions: v-slot:activator="{ on }" and v-on="on". The question is - is there's a way in Vue/Vuetify to merge this constructions and get the desired behavior?
At the moment I found one way to get what I want by adding addtional <a> tag:
<template>
<v-data-table :headers="headers" :items="tableItems">
<template v-slot:item="props">
<tr>
<td>{{ props.item.text }}</td>
<td>
<some-modal>
<template v-slot:activator="{ on }">
<a v-on="on">
<v-tooltip bottom>
<template v-slot:activator="{ on }">
<v-icon v-on="on" small class="mr-2">delete</v-icon>
</template>
<span>Tooltip message</span>
</v-tooltip>
</a>
</template>
</some-modal>
</td>
</tr>
</template>
</v-data-table>
</template>
But maybe there are any ways to merge v-slot:activator and v-on without an addtional <a> tag?
Codesandbox with current behavior

Stumbled upon solution here, credits to #Yom T.
<v-menu>
<template #activator="{ on: onMenu }">
<v-btn v-on="onMenu">Menu Trigger</v-btn>
<v-tooltip bottom>
<template #activator="{ on: onTooltip }">
<v-btn v-on="{ ...onMenu, ...onTooltip }">Menu Trigger with Tooltip</v-btn>
</template>
<span>Tooltip Content</span>
</v-tooltip>
</template>
</v-menu>

Related

Converting Vuetify 1.x v-slot activator to 2.x via v-data-table

I have a piece of working code from Veutify 1.5.6 that includes an icon inside of a data table that, when clicked, displays a menu. When clicked the activator shows the list that was activated.
I have a codepen with this example
I want the same functionality, but Vuetify 2 does not have slot="activator".
It looks like they use v-slot:activator="{ on }" with a template tag, but I can't get this replicated over.
This is my attempt at it.
<v-data-table
:headers="labels"
:items="data"
>
<template v-slot:[`item.statusIcon`]="{ item }">
<td style="cursor: pointer;">
<v-icon :class="item.status">{{item.statusIcon}}
<template v-slot:activator="{ on }">
<v-list>
<v-list-item
v-on="on"
v-for="(status, index) in statusItems"
:key="index"
:class="status.title"
#click="setStatus(item, status.title)"
>{{ status.title }}></v-list-item>
</v-list>
</template>
</v-icon>
</td>
</template>
</v-data-table>
There's definitely something small I'm missing and I know that the v-icon should be under the template, but I keep getting this error
'v-slot' directive must be owned by a custom element, but 'td', 'div', 'template' is not
I found this thread, but still no help.
Any help would be appreciated
You should wrap the icon with v-menu component then use this icon as menu activator :
<v-menu offset-y>
<template v-slot:activator="{ on, attrs }">
<v-icon v-on="on" :class="item.status">{{item.statusIcon}}
</v-icon>
</template>
<v-list>
<v-list-item
v-for="(status, index) in statusItems"
:key="index"
:class="status.title"
#click="setStatus(item, status.title)"
>{{ status.title }}></v-list-item>
</v-list>
</v-menu>

how to access parent v-data-table from template in nested v-data-table?

I have a page made with vue using vuetify. It displays a v-data-table which can be expanded to reveal another v-data-table, like this:
<div class="subsection">
<v-data-table
:headers="prescriptionHeaders"
:items="pendingItems"
show-expand
item-key="id"
>
<template v-slot:expanded-item="{headers,item}">
<td :colspan="headers.length">
<v-data-table
:headers="pendingPrestationHeaders"
:items="item.prestations"
v-model="selected"
>
<template v-slot:[`item.actions`]="{ item }">
<div class="table-row-actions">
<v-tooltip left v-if="item.categeoryTypeId === 6">
<template v-slot:activator="{ on, attrs }">
<v-icon
v-bind="attrs"
v-on="on"
#click="func1(item)"
class="action-doc"
>
mdi-file-document-outline
</v-icon>
</template>
<span>blablabla</span>
</v-tooltip>
</div>
</template>
</v-data-table>
</td>
</template>
</v-data-table>
</div>
the problem is that I need to call func1 with a property of the item from the outer v-data-table. How can I access it from within my <template v-slot:[`item.actions`] template ? I know I could include a reference to the parent item in my child item, or just duplicate the data that I need from the parent into the child (that's what I'm currently doing), but I was just curious to find out whether there is a way to refer to the "outer" item in the template slot, but I guess not.
To access the item of the outer v-data-table, you need to change the inner data table with props.item
Something like this should work.
<template v-slot:[`props.item.actions`]="{ props.item }">
<div class="table-row-actions">
<v-tooltip left v-if="props.item.categeoryTypeId === 6">
<template v-slot:activator="{ on, attrs }">
<v-icon
v-bind="attrs"
v-on="on"
#click="func1(item)"
class="action-doc"
>
mdi-file-document-outline
</v-icon>
</template>
<span>blablabla</span>
</v-tooltip>
</div>
</template>
I've exactly the same challenge. I want to access to item ID of the outer v-data-table from the inner one. The paragraph shows the data correctly. How to access this value from the inner data-table?
<template v-slot:expanded-item="{ item }">
<td :colspan="attachmentHeaders.length">
<p>{{item.finDocId}}</p>
<v-data-table
:headers="attachmentHeaders"
:items="item.attachmentPlainDtos"
item-key="finDocId"
disable-pagination
:hide-default-footer="true"
no-data-text='Geen bijlagen'
>
<template v-slot:[`item.attachmentActions`]="{ item }">
<v-icon large #click="removeAttachment(item.id, item.attachmentId)">
mdi-delete
</v-icon>
</template>
</v-data-table>
</td>
</template>

How can I wrap a v-switch with a v-tooltip with Vuetify?

I attempted doing this like in the documentation
https://vuetifyjs.com/en/components/tooltips/
<v-tooltip color="black" bottom >
<template v-slot:activator="{ on, attrs }">
<v-switch
v-model="boo"
v-bind="attrs"
v-on="on"
inset
>
</v-switch>
</template>
<div>
Tooltip
</div>
</v-tooltip>
here :
https://codepen.io/julienreszka/pen/BazvmYN
But the tooltip isn't displayed and the css is wrong.
not really sexy, but you can wrap your switch in a div
<div
v-on="on"
v-bind="attrs">
<v-switch
v-model="boo"
></v-switch>
</div>
v-tooltip is label of v-switch
<v-switch
v-model="boo"
inset>
<template v-slot:label>
<v-tooltip color="black" bottom>
<template v-slot:activator="{ on, attrs }">
<span
v-bind="attrs"
v-on="on">switch label</span>
</template>
Tooltip
</v-tooltip>
</template>
</v-switch>
switches document

Vuetify: Using v-tooltip within a v-for?

I am trying to use the v-tooltip in a v-for but I think my binding is incorrect, and blocking it from rendering. I've used this outside of the v-for and it works as expected:
<div v-for="item in items">
<v-tooltip bottom>
<template v-slot:activator="{ on, attrs }">
Hover to View
</template>
<span>{{ item.name }} </span>
</v-tooltip>
</div>
You should use v-bind and v-on inside the template like this:
<span v-bind="attrs" v-on="on">Hover to View</span>
In your example:
<div v-for="item in items" :key="item.id">
<v-tooltip bottom>
<template v-slot:activator="{ on, attrs }">
<span v-bind="attrs" v-on="on">Hover to View</span>
</template>
<span>{{ item.name }}</span>
</v-tooltip>
</div>

Switching child components inside v-data-table using buttons(filters)

I have a parent component with 2 buttons that I want to use as filters. the child component is called inside a v-data-table.
ScanGrid(parent):
<template>
<v-card class="ma-5" v-else>
<v-flex row xs12 class="pa-3 ml-3">
<div class="mr-3 mt-2">
<h3>Regrouper par :</h3>
</div>
<div>
<v-btn-toggle color="success" v-model="groupBy">
<v-btn
text
value="barCode"
class="lowerCase"
v-ripple="{ class: 'success--text' }"
>
Code barre
</v-btn>
<v-btn
text
value="productDef"
class="lowerCase"
v-ripple="{ class: 'success--text' }"
>
Définition de produit
</v-btn>
</v-btn-toggle>
</div>
</v-flex>
<v-card-text>
<v-layout align-center>
<v-data-table
:headers="headers"
:items="items"
item-key="StorageName"
show-expand
single-expand
:expanded="expanded"
hide-default-footer
#click:row="clickedRow"
>
<template v-slot:expanded-item="{ item }">
<td :colspan="12">
<ScanGridCode :item="item"></ScanGridCode>
</td>
</template>
<template v-slot:expanded-item="{ item }">
<td :colspan="12">
<ScanGridDef :item="item"></ScanGridDef>
</td>
</template>
</v-data-table>
</v-layout>
</v-card-text>
</v-card>
</template>
The children components I want to switch using the buttons are called ScanGridCode and ScanGridDef inside templates in v-data-table. I tried to find examples of filtering buttons online but couldn't find anything like what I want to do.
I'm using Vue 2.6.10 with Vuetify 2.1.7
You're almost done already, since you already have the v-btn-toggle set up with v-model="groupBy". All you still need is to add v-if to each template, like:
<template v-if="groupBy=='barCode'" v-slot:expanded-item="{ item }">