Vuetify: Using v-tooltip within a v-for? - vue.js

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>

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: Use v-chip-group inside a v-select selection slot

I am trying to add a v-chip-group in a v-select v-slot=selection but am failing.
Due to design requirements, I have to persist some placeholder text in a multi-select but only have so much width for the component. I want the chips to overflow to the right with a scroll interface like the default v-chip-group but can't seem to work it together.
Goal
Current
How can I get the proxy BaseSelect component, which is basically a wrapper for default styling of a v-select, to work as v-chip-group? I also want the chips to work with the deletable-chips prop.
Component
<BaseSelect
multiple
class="flex-0-1-30rem"
localKey="breakdownBy"
:items="localizedBreakdownList"
:value="breakdowns"
:placeholder="$t('select-breakdownBy-label')"
#change="setBreakdowns"
>
<template v-slot:selection="{ item, select, index }">
<span
v-if="index === 0"
class="text--uppercase"
>{{ $t('select-breakdownBy-label') }}</span>
<v-chip color="primary" class="text--white">{{ item.text }}</v-chip>
</template>
</BaseSelect>
BaseSelect component
<template>
<v-select
hide-details
solo
dense
:append-icon="mdiMenuDown"
:items="items"
v-bind="$attrs"
v-on="$listeners"
>
<!-- Passes scopedSlots to child -->
<template v-for="(_, slot) of $scopedSlots" v-slot:[slot]="scope">
<slot :name="slot" v-bind="scope" />
</template>
<!-- Default scopedSlots -->
<template v-if="!hasScopedSlot('selection')" v-slot:selection="{ item }">
<span
:class="slotClasses"
>{{ item.text || $t(`select-${localKey}-option-${item.value || item}`) || item }}</span>
</template>
<template v-if="!hasScopedSlot('item')" v-slot:item="{ item }">
<span
:class="slotClasses"
>{{ item.text || $t(`select-${localKey}-option-${item.value || item}`) || item }}</span>
</template>
</v-select>
</template>

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

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>