Vuetify v-data-table render multiple v-edit-dialog - vue.js

The docs has example for adding inline edit dialog to a column. I'm trying to add it to each column.
Copy & Paste of course.
Rendering row - But it will remove default function (i.e: sortable) of v-data-table row --> I don't choose
Using v-for with v-slot - But has error demo
<template v-for="header in headers" v-slot:item[header.value]="propsAPI">
<v-edit-dialog
:return-value.sync="propsAPI.item[header.value]"
#save="save"
#cancel="cancel"
#open="open"
#close="close"
:key="header.value"
>
{{ propsAPI.item[header.value] }}
<template v-slot:input>
<v-text-field
v-model="propsAPI.item[header.value]"
:rules="[max25chars]"
label="Edit"
single-line
counter
/>
</template>
</v-edit-dialog>
</template>
Any suggestion

You can replace
<template v-for="header in headers" v-slot:item[header.value]="propsAPI">
with
<template v-for="header in headers" v-slot:[`item.${header.value}`]="propsAPI">
This should redefine slot for each column.

Related

How can i convert v-data-table to v-select in vuetify?

I already have a v-data-table of vuetify and i want to convert its contents from a data table to a drop down using v-select. How is it possible to do the change?
<v-data-table
dense
v-if="requester_details.credential_type == 'TEMPLATE'"
class="elevation-0"
hide-default-footer
:headers="templateResultHeaders"
#click:row="handleRowClickTemplate"
:items="GetAllTemplatesList"
:no-data-text="noDataText"
>
<template v-slot:[`item.template_name`]="{ item }">
<div>{{ item.template_name }}</div>
</template>
<template v-slot:[`item.Action`]="{}">
<v-icon color="primary">mdi-chevron-right</v-icon>
</template>
</v-data-table>
Well did this and it works as expected. Writing "return object" is important to open the content of the v-select fields
<v-select
v-if="requester_details.credential_type == 'TEMPLATE'"
class="FontSize field_height field_label_size"
dense
placeholder="Template items"
outlined
:items="GetAllTemplatesList"
item-text="template_name"
#change="handleRowClickTemplate"
return-object
>
</v-select>

vuetify: why the table is sorted whenever the user clicks into the input field

I have a vuetify datatable, the original solution is dynamic allocation of search text field using v-for for each of the column and then multi filter is implemented. following is my solution:
<template v-for="(header, i) in columns" v-slot:[`header.${header.value}`]="{ }">
{{ header.text }}
<v-text-field :key="i"
v-model="multiSearch[header.value]"
class="pa"
type="text"
:placeholder="header.value"
prepend-inner-icon="mdi-magnify"
></v-text-field>
</template>
The problem is whenever an user clicks on the text field of a particular column, the sorting function also runs at the same time. I have a miniature solution on the following pen which has the same behaviour. I tried to put one div after template tag but still the same. Kindly have a look at it. Any help would be appreciated.
Code Pen
Wrap the text field with a DIV and attach an empty handler to prevent the bubbling of CLICK events:
<template v-for="(header, i) in columns" v-slot:[`header.${header.value}`]="{ }">
{{ header.text }}
<div #click.stop>
<v-text-field :key="i"
v-model="multiSearch[header.value]"
class="pa"
type="text"
:placeholder="header.value"
prepend-inner-icon="mdi-magnify"
></v-text-field>
</div>
</template>

How to use v-for to create slot content for multiple slots

I have a table in vuetify where I want to create a template for 14 of the columns. Instead of making 14 different templates like this:
<v-data-table disable-pagination
:headers="headers"
:items="users"
:search="search"
:hide-default-footer="true"
>
<template v-slot:[`item.date_0`]="{ item }">
<ScheduleIcon :item="item.date_0" />
</template>
<template v-slot:[`item.date_1`]="{ item }">
<ScheduleIcon :item="item.date_1" />
</template>
<template v-slot:[`item.date_2`]="{ item }">
<ScheduleIcon :item="item.date_2" />
</template>
</v-data-table>
I want to make a v-for loop with an index from 0-13 and at the same time use that index-value in the slot and props variables. Something like this is pseudo-code:
<template v-slot:[`item.date_INDEX`]="{ item }" v-for="index in 13" :key="index">
<ScheduleIcon :item="item.date_INDEX" />
</template>
How would I do this? The v-for give me the following error:
<template> cannot be keyed. Place the key on real elements instead.
Your "pseudo code" is almost right...
This should work:
<template v-slot:[`item.date_${index-1}`]="{ item }" v-for="index in 14">
<ScheduleIcon :item="item[`date_${index-1}`]" :key="index" />
</template>
key is not allowed or needed on slot content (<template>) even if it is in v-for. Remove it or place it on ScheduleIcon component...

Vuetify data table - manually display expandable rows

I have a bunch of dynamic columns in a v-data table which I need to loop through and interrogate in order to display the correct info. It looks a bit like this (taken from the answer here: Vuetify format cell based on item type)
<v-data-table :item="items" ... >
<template v-for="header in headers" v-slot:[`item.${header.value}`]="{ item } ">
<template v-if="header.type === 'foo'">
<span style="color: red;">{{ item[header.value] }}</span>
</template>
<template v-else-if="header.value === 'data-table-expand'">
???
</template>
<template v-else>
{{ item[header.value] }}
</template>
</template>
</v-data-table>
Since I need the v-if statement, all other types default to the v-else. However, the v-else is not suitable for when a type is an expandable row. It will display a blank value for that column. So I created a v-else-if template to be able to capture the expandable row column and correctly render it to the screen.
The problem is that I don't know what to put in the template to indicate it's a column with expandable rows (https://vuetifyjs.com/en/components/data-tables/#expandable-rows). In other words it does not render the carat icon that shrinks/expands the subtable, nor does it render the clickable actions. How would I modify the v-else-if template to correctly render its contents?
I came up with a workaround using computed properties.
Instead of using
v-for="header in headers"
I changed it to a computed headers which is filtered.
<template v-for="header in headersIWant" v-slot:[`item.${header.value}`]="{ item } ">
<span style="color: red;">{{ item[header.value] }}</span>
</template>
...
computed: {
headersIWant() {
return this.headers.filter(x => x.type === 'foo');
}
}

How to record changes made in vuetify Datatables?

In the given link we can edit some columnn How to record/console those changes so that we can pass that changed data to other component Check link
<v-edit-dialogue> is used
Inline editing is achieved by using first the scoped slot of the <v-data-table /> component. Within the scoped slot, you use <v-edit-dialog /> component. And within the input slot of the edit dialog component, you use the <v-text-field /> component.
So, just bind to the input or change event of the text field component, and you have the hook you are looking for.
<v-data-table>
<template slot="items" slot-scope="props">
<td>
<v-edit-dialog>
{{ props.item.name }}
<v-text-field
slot="input"
v-model="props.item.name"
#input="onEditValueChanged" <---------
></v-text-field>
</v-edit-dialog>
</td>
</template>
</v-data-table>