Vuetify: Use v-chip-group inside a v-select selection slot - vue.js

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>

Related

How do i add action column with 'edit' and 'delete' buttons?

I want to add action column in the table with delete and edit buttons in it. Table in the image is output of the coded below. An action column is needed in the table in order to perform actions i.e edit and delete.
Table
Code for the table
<b-table
responsive
class="mb-0"
head-variant="light"
:items="items"
:current-page="currentPage"
:per-page="perPage"
>
<template #cell(id)="data"> #{{ data.item.id }} </template>
<template #cell(user)="data">
<b-img
:src="require('#/assets/images/users/' + data.item.user.image)"
rounded="circle"
:alt="data.item.user.image"
width="40"
/>
<span class="ml-2 fw-medium"
>{{ data.item.user.first }} {{ data.item.user.last }}</span
>
</template>
<template #cell(team)="data">
<b-img
:src="require('#/assets/images/users/' + data.item.team.teamimg1)"
rounded="circle"
:alt="data.item.team.teamimg1"
width="35"
class="mr-n2 border border-white"
/>
<b-img
:src="require('#/assets/images/users/' + data.item.team.teamimg2)"
rounded="circle"
:alt="data.item.team.teamimg2"
width="35"
class="mr-n2 border border-white card-hover"
/>
<b-img
:src="require('#/assets/images/users/' + data.item.team.teamimg3)"
rounded="circle"
:alt="data.item.team.teamimg3"
width="35"
class="border border-white"
/>
</template>
<template #cell(status)="data">
<b-badge
pill
:class="`px-2 text-white badge bg-${data.item.status.statusbg}`"
>
<i class="font-9 mdi mdi-checkbox-blank-circle"></i>
{{ data.item.status.statustype }}
</b-badge>
</template>
<template #cell(action)="data">
<b-button variant="light" #click="deleteUser(data.item.user.id)">
<feather type="delete" class="feather-sm"></feather>
</b-button>
</template>
</b-table>
I'd suggest you to use the b-dropdown element (more info here). Your table would then have one column with an "action" description and have a b-dropdown button for each row:
<b-table
responsive
class="mb-0"
head-variant="light"
:items="items"
:current-page="currentPage"
:per-page="perPage"
>
<template #cell(id)="data"> #{{ data.item.id }} </template>
<!--......-->
<template #cell(action)="data">
<b-dropdown
right
variant="primary"
>
<template v-slot:button-content>
Select One
</template>
<b-dropdown-item v-on:click="edit(data.item)">
Edit
</b-dropdown-item>
<b-dropdown-item v-on:click="delete(data.item)">
Delete
</b-dropdown-item>
</b-dropdown>
</template>
</b-table>
Then, in your methods, just add:
edit: function(myObject) {
console.log(myObject);
//Do something here
},
delete: function(myObject) {
console.log(myObject);
//Do something here
},
You could also add one column for each edit and delete feature. In this case, simply create a normal b-button and just call the v-on:click="edit(data.item)" and v-on:click="remove(data.item)" the same way it was implemented on the b-dropdown-items

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>

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>

Can't Select Customized Combobox Items (Vuetify)

Two problems that I'm having with Vuetify's combobox:
Input is cleared on blur (combobox not focused on) and I don't want this. This doesn't happen if I don't customize how my items look with v-slot:item though.
Can't select any of the items when I'm trying to customize my items with v-slot:item, but I can select them if I don't customize the items.
I don't know what I'm doing wrong when I basically just copied straight from the documentation and adjusted it to my needs.
<v-combobox
#focus="isShaped = true"
#blur="isShaped = false"
v-model="card_name"
:loading="isLoading"
:items="cards"
hide-no-data
prepend-inner-icon="mdi-magnify"
append-icon=""
outlined rounded :shaped="isShaped"
label="Search for a card"
:search-input.sync="search"
item-text="name"
item-value="set_name"
>
<template v-slot:item="{ item }">
<v-list-item>
<v-list-item-content>
<v-list-item-title class="mb-2">{{item.name}}</v-list-item-title>
<v-list-item-subtitle>{{item.set_name}}</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
</template>
<template v-slot:selection="{ item }">
<span v-text="item.name"></span>
</template>
<template v-slot:progress>
<v-progress-circular
class="mt-3"
v-if="isLoading"
indeterminate
color="primary"
:width="2"
:size="30"
></v-progress-circular>
</template>
</v-combobox>
Here's the codepen: https://codepen.io/chataolauj/pen/RwwYxBg?editors=1010

VUETIFY - How to pass slot to nested select component

I'm using last version of vuetify and trying to figure out how to make slots work. Documentation about select may be find here
VSelectWithValidation
<v-select v-model="innerValue" :error-messages="errors" v-bind="$attrs" v-on="$listeners">
<template slot="selection" slot-scope="data">
{{ data.item.name }}
</template>
<template slot="item" slot-scope="data">
{{ data.item.name }} - {{ data.item.description }}
</template>
</v-select>
TestComponent
<VSelectWithValidation
rules="required"
:items="items"
v-model="select"
label="Select">
// I WOULD LIKE SLOTS TO BE AT THIS LEVEL
</VSelectWithValidation>
Basically, I would like the slots to be customized so I need to move them out of the VSelectWithValidation component to be set on the TestComponent
I tried different variations with no success.
https://codesandbox.io/s/veevalidate-components-vuetify-u11fd
VSelectWithValidation
You need to create slot inside your template slot item and bind scope data to able to use from other component ..
<template slot="item" slot-scope="data">
<slot name="item" v-bind="data"></slot>
</template>
TestComponent
You can access that slot by writing v-slot:YourSlotName="hereIsBindData"
<template v-slot:item="data">
{{ data.item.name }} // you can code here whatever you like
</template>