How to clear only selected row in data-table, vuetify [duplicate] - vue.js

This question already has an answer here:
How to clear selected row in v-data-table, Vuetify
(1 answer)
Closed 2 years ago.
I have a vue app where Im using v-data table with show-select option. I want to clear only selected data using "cancel" button and Im looking for solution how to do it correctly. Already I can clear all data from table onclick.
Example on picture:
I want to clear only selected row(Ice cream sandwich)
Here is my code:
Table:
<v-data-table
v-model="selected"
:headers="headers"
:items="desserts"
:single-select="singleSelect"
item-key="name"
show-select
class="elevation-1"
>
<template v-slot:top>
<v-switch
v-model="singleSelect"
label="Single select"
class="pa-3"
></v-switch>
</template>
</v-data-table>
"cancel" button
<v-btn class="ma-2" color="primary" #click="cancel"> Cancel </v-btn>
script
cancel() {
this.desserts = [];
},

Use any unique property (in this example - an id) to filter the row out of your items array.
cancel(){
this.desserts = this.desserts.filter((e)=> {
return e.id !== this.selected.id;
});
}

Related

Vuetify v-data-table header customization

I have customized the v-data-table header with text-field for searching to make the function compact. But I can not prevent the sort click function on text-field.
Step to Reproduce:
<div id="app">
<v-app>
<v-main>
<v-data-table
:headers="headers"
:items="desserts"
:items-per-page="5"
class="elevation-1"
>
<template v-slot:header.calories="{ header }">
<v-text-field label="search calories"></v-text-field>
</template>
</v-data-table>
</v-main>
</v-app>
</div>
Please click this Codepen link
Please click on search calories one to two times, it sorts asc or desc.
I want to stop the sort function only on the header text or custom text-field, because there is a sort icon right side of it.
Put a #click.stop on the v-text-field:
<template v-slot:header.calories="{ header }">
<v-text-field label="search calories" #click.stop />
</template>
This will stop the click event from propagating into the header.

How can I pass a v-data-table row information to child element

I have creating a list of users want to add them tags. I am using a data-table to display them and a combo box using chips to add or remove tags. How can I pass the user information to the method called when I add / remove a tag? Here is my code:
<v-data-table :headers="headers" :items="usersInfos" :search="search" :items-per-page="-1">
<template v-slot:[`item.tags`]="{ item }">
<v-combobox v-model="item.tags" :items="roles" chips clearable label="RĂ´les" multiple>
<template v-slot:selection="{ attrs, item, select, selected }">
<v-chip
v-bind="attrs"
:input-value="selected"
close
#click="select"
#click:close="removeRole(item)"
>
{{ item }} <!-- the tag -->
</v-chip>
</template>
</v-combobox>
</template>
</v-data-table>
Don't know if I understood it correctly but you can do following pass your item with your click event to your methods - call the function and use the passed parameter there.
in your template
#click=getSelectedItem(usersInfos)
in your script
methods: {
getSelectedItem(usersInfos) {
//do code here
console.log(usersInfos)
}
}
and than you have to use this where you have written your child element:
<child :usersInfo="usersInfo">
and in your child.vue you have to set props in your script like this:
props: ["usersInfo"]

How to receive row Id when row is selected

I am using v-data-table and I want get row Id when a row selected.
this is my code
<v-data-table
item-key="id"
v-model="selected"
show-select
:headers="headers"
:items="users">
</v-data-table>
Something that give me when I select a row:
[
{id:2 , name:"kevin" , age : 25 }
]
Something I need it to be:
[2]
Upon using the v-data-table you can use the v-model in the table.
And then you can watch for your selected array and get the field you want from it.
<v-data-table
v-model="selected"
:headers="headers"
:items="desserts"
:single-select="singleSelect"
item-key="name"
show-select
class="elevation-1"
>
As you see the selected is an array I defined in the data section.
data () {
return {
singleSelect: false,
selected: []
}

By changing a slot to scoped slot, it no longer appears on this.$slots and this.$scopedslots

I have a parent component and a child component (which has a vuetify table).
I am trying to make certain columns display chips from the parent component. I've run into a weird problem which I'm not sure what is the matter.
Parent Page: (Parent page is more complicated than this which is why I have taken out the table into another component so I can reuse it in combination with other stuff elsewhere)
<simple-table
v-if="!loading"
:tableData="tableData"
:loading="loading"
:headers="headers"
#search=""
:selected.sync="selected"
itemKey="groupName"
>
<template v-slot:userDatasetAccess="">
<v-chip color="red" dark>test</v-chip>
</template>
</simple-table>
When the code is like above, I can see test in a chip appearing in the UserDatasetAccessColumn
Child Page
<v-data-table
:headers="headers"
:items="tableData"
:search="search"
:loading="loading"
loading-text="Loading... Please Wait"
show-select
:item-key="itemKey"
v-model="selected"
#input="$emit('update:selected',selected)"
>
<template v-slot:[getSlot(slot)]="{ item }" v-for="(_, slot) in $slots">
<slot :item="item" :name="slot"></slot>
</template>
</v-data-table>
methods: {
getSlot(slot) {
return `item.${slot}`
}
},
However, when I change the parent to:
<template v-slot:userDatasetAccess="item">
<v-chip color="red" dark>{{item.userDatasetAccess}}</v-chip>
</template>
It no longer works.
I've console logged this.$slots and this.$scopedslots and they become empty.
So my question is: Why is it that when I do v-slot:userDatasetAccess="" vs v-slot:userDatasetAccess="item", it no longer appears as part of $slots and $scopedslots.
Is there a better way to access the columns via slots from the parent?

Vuetify Datatable - Rendering element on first row only

i have a problem on a vue project of mine.
i have a vuetify datatable that receives data from a .net core backend with mongo.
it works just fine and every row have a edit and delete buttons. but in this case i need to limit edit and delete buttons to show only on the first row of the datatable.
i've tried a lot of solutions from the internet but none of them worked for me so far.
here's the code for the datatable and the buttons, respectively:
<v-data-table
:headers="headers"
:items="pacientes"
:search="search"
:page.sync="page"
:items-per-page="itemsPerPage"
hide-default-footer
sort-by="status"
class="elevation-1"
#page-count="pageCount = $event"
>
<template
v-slot:item.edit="{ item }" >
<v-btn
color="blue"
tile
x-large
icon
#click="aprovar(item.nomePaciente, item.idEspera, item.matricula)"
>
<v-icon>mdi-pencil-circle</v-icon>
</v-btn>
</template>
<template
v-slot:item.delete="{ item }"
>
<v-btn
color="red"
x-large
tile
icon
#click="abrirModalDeletar(item.nomePaciente, item.idEspera)">
<v-icon>mdi-delete-circle</v-icon>
</v-btn>
</template>
Any help would be appreciated, thanks!
You could introduce a boolean property to your items in the array, let's call it isFirst Then you could listen to the event of current-items in the data table, which returns the current items in view. And based on that, show the buttons for the first row. So I suggest the following:
<v-data-table #current-items="setFirst" ...... >
And the function:
methods: {
setFirst: function(currItems) {
// first check that actually exists values
if (currItems.length) {
// toggle all to false
currItems.forEach(x => x.isFirst = false)
// just set first to true
currItems[0].isFirst = true;
}
}
},
and then set an v-if to the buttons:
<v-btn v-if="item.isFirst" ....>
CODEPEN
If your object has an ID and you know what that ID is, you can set a v-if statement for your edit and delete buttons to only render when the ID is equal to that value. Something like this:
<template
v-slot:item.edit="{ item }" >
<v-btn
color="blue"
tile
v-if="item.id===1"
x-large
icon
#click="aprovar(item.nomePaciente, item.idEspera, item.matricula)"
>
<v-icon>mdi-pencil-circle</v-icon>
</v-btn>
</template>
<template
v-slot:item.delete="{ item }"
>
<v-btn
color="red"
x-large
tile
v-if="item.id===1"
icon
#click="abrirModalDeletar(item.nomePaciente, item.idEspera)">
<v-icon>mdi-delete-circle</v-icon>
</v-btn>
</template>
If your item doesn't have an ID, when you fetch your data, you can programmatically set a property on the first item and then use the v-if statement on that property.
Something like:
fetchData().then(items => {
if (items.length >= 1) {
items[0].showEditDelete = true
}
})
Then your v-if statement will look like v-if=item.showEditDelete.