Scroll to first selected row in v-data-table - vue.js

I have a v-data-table that I highlight a selected row by adding a selectedRow class to the table row. After an update in another component the v-data-table is refreshed. I want it to automatically scroll back to the selected row. I'm getting an error that the element cannot be found. It seems to not be finding the CSS selector I am trying to pass as the target.
mounted: function () {
eventBus.$on("refreshVendors", () => {
this.getVendors();
// add scrollTo first selected vendor
this.$vuetify.goTo(".selectedRow");
});
this.clearSelectedVendors();
this.getVendors();
},
I've tried using next tick but same error occurs.

For current version=v2.3.6 now, The CSS class for selected row is v-data-table__selected, so changes that line to this.$nextTick(() => this.$vuetify.goTo('.v-data-table__selected')).
Below is one demo based on the snippet in official site:
PS: hit 'Goto' button at the end of the fiddle then you will see the effect.
new Vue({
el: '#app',
vuetify: new Vuetify(),
methods: {
gotoSelectedRow: function () {
this.desserts[1].selected = false
this.desserts[0].selected = true
this.$nextTick(() => this.$vuetify.goTo('.selectedRow'))
}
},
data () {
return {
headers: [
{
text: 'Dessert (100g serving)',
align: 'start',
sortable: false,
value: 'name',
},
{ text: 'Calories', value: 'calories' },
{ text: 'Fat (g)', value: 'fat' },
{ text: 'Carbs (g)', value: 'carbs' },
{ text: 'Protein (g)', value: 'protein' },
{ text: 'Iron (%)', value: 'iron' },
],
desserts: [
{
name: 'Frozen Yogurt',
calories: 159,
fat: 6.0,
carbs: 24,
protein: 4.0,
iron: '1%',
},
{
name: 'Ice cream sandwich',
calories: 237,
fat: 9.0,
carbs: 37,
protein: 4.3,
iron: '1%',
selected: true
},
{
name: 'Eclair',
calories: 262,
fat: 16.0,
carbs: 23,
protein: 6.0,
iron: '7%',
},
{
name: 'Cupcake',
calories: 305,
fat: 3.7,
carbs: 67,
protein: 4.3,
iron: '8%',
},
{
name: 'Gingerbread',
calories: 356,
fat: 16.0,
carbs: 49,
protein: 3.9,
iron: '16%',
},
{
name: 'Jelly bean',
calories: 375,
fat: 0.0,
carbs: 94,
protein: 0.0,
iron: '0%',
},
{
name: 'Lollipop',
calories: 392,
fat: 0.2,
carbs: 98,
protein: 0,
iron: '2%',
},
{
name: 'Honeycomb',
calories: 408,
fat: 3.2,
carbs: 87,
protein: 6.5,
iron: '45%',
},
{
name: 'Donut',
calories: 452,
fat: 25.0,
carbs: 51,
protein: 4.9,
iron: '22%',
},
{
name: 'KitKat',
calories: 518,
fat: 26.0,
carbs: 65,
protein: 7,
iron: '6%',
},
],
}
},
})
.selectedRow
{
color: red;
}
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/#mdi/font#5.x/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/babel-polyfill/dist/polyfill.min.js"></script>
<div id="app">
<v-app id="inspire">
<v-data-table
:headers="headers"
:items="desserts"
item-key="name"
class="elevation-1"
>
<template v-slot:top>
<v-switch v-model="singleSelect" label="Single select" class="pa-3"></v-switch>
</template>
<template v-slot:body="{ items }">
<tbody>
<tr v-for="item in items" :key="item.name" :class="{'selectedRow': item.selected}">
<td>{{ item.name }}</td>
<td>{{ item.calories }}</td>
<td>{{ item.fat }}</td>
<td>{{ item.carbs }}</td>
<td>{{ item.protein }}</td>
<td>{{ item.iron }}</td>
</tr>
</tbody>
</template>
</v-data-table>
<button #click="gotoSelectedRow()">Goto</button>
</v-app>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue#2.x/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.js"></script>

Related

Trying to render a v-data-table in a v-dialog does not work

I am trying to implement a v-data-table in a v-dialog
<v-dialog max-width = '600px' v-model = 'dialog'>
<v-card>
<v-card-title>
<span class = "headline"> Reconstructor </span>
</v-card-title>
<draggable :list = "draggableList">
<!--<div v-for = "(item, index) in draggableList" :key = "index">
{{item.fieldValue}} , {{item.fieldName}}
</div> -->
<v-data-table :header = 'headersList' :items = 'draggableList'>
</v-data-table>
</draggable>
</v-card>
</v-dialog>
Even if i remove the draggable component nothing changes.
I manually verified the headersList and the draggableList and they are correct. Sorry if it is a begginer mistake but it is my first project in vue.
Your code looks fine, I just created a working code snippet below with the same code you posted in post. Can you please have a look and see if it helps.
new Vue({
el: '#app',
vuetify: new Vuetify(),
data () {
return {
dialog: true,
headers: [
{
text: 'Dessert (100g serving)',
align: 'start',
sortable: false,
value: 'name',
},
{ text: 'Calories', value: 'calories' },
{ text: 'Fat (g)', value: 'fat' },
{ text: 'Carbs (g)', value: 'carbs' },
{ text: 'Protein (g)', value: 'protein' },
{ text: 'Iron (%)', value: 'iron' },
],
desserts: [
{
name: 'Frozen Yogurt',
calories: 159,
fat: 6.0,
carbs: 24,
protein: 4.0,
iron: '1%',
},
{
name: 'Ice cream sandwich',
calories: 237,
fat: 9.0,
carbs: 37,
protein: 4.3,
iron: '1%',
},
{
name: 'Eclair',
calories: 262,
fat: 16.0,
carbs: 23,
protein: 6.0,
iron: '7%',
},
{
name: 'Cupcake',
calories: 305,
fat: 3.7,
carbs: 67,
protein: 4.3,
iron: '8%',
},
{
name: 'Gingerbread',
calories: 356,
fat: 16.0,
carbs: 49,
protein: 3.9,
iron: '16%',
},
{
name: 'Jelly bean',
calories: 375,
fat: 0.0,
carbs: 94,
protein: 0.0,
iron: '0%',
},
{
name: 'Lollipop',
calories: 392,
fat: 0.2,
carbs: 98,
protein: 0,
iron: '2%',
},
{
name: 'Honeycomb',
calories: 408,
fat: 3.2,
carbs: 87,
protein: 6.5,
iron: '45%',
},
{
name: 'Donut',
calories: 452,
fat: 25.0,
carbs: 51,
protein: 4.9,
iron: '22%',
},
{
name: 'KitKat',
calories: 518,
fat: 26.0,
carbs: 65,
protein: 7,
iron: '6%',
},
],
}
},
})
<script src="https://unpkg.com/vue#2.x/dist/vue.js"></script>
<script src="https://unpkg.com/vuetify#2.6.7/dist/vuetify.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/vuetify#2.6.7/dist/vuetify.min.css"/>
<div id="app">
<v-app id="inspire">
<v-dialog max-width='600px' v-model='dialog'>
<v-card>
<v-card-title>
<span class = "headline"> Reconstructor </span>
</v-card-title>
<v-data-table :headers="headers" :items="desserts">
</v-data-table>
</v-card>
</v-dialog>
</v-app>
</div>

How to set border on specific row of Vuetify table?

I am trying to set the border-left property to specific rows of the v-data-table instead of the whole table like seen in this Codepen. How do I access that?
Uses the slot=item, then apply the styles depending on scoped-slot.
Below is one example:
new Vue({
el: '#app',
vuetify: new Vuetify(),
data () {
return {
headers: [
{
text: 'Dessert (100g serving)',
align: 'start',
sortable: false,
value: 'name',
},
{ text: 'Calories', value: 'calories' },
{ text: 'Fat (g)', value: 'fat' },
{ text: 'Carbs (g)', value: 'carbs' },
{ text: 'Protein (g)', value: 'protein' },
{ text: 'Iron (%)', value: 'iron' },
],
desserts: [
{
name: 'Frozen Yogurt',
calories: 159,
fat: 6.0,
carbs: 24,
protein: 4.0,
iron: '1%',
},
{
name: 'Ice cream sandwich',
calories: 237,
fat: 9.0,
carbs: 37,
protein: 4.3,
iron: '1%',
},
{
name: 'Eclair',
calories: 262,
fat: 16.0,
carbs: 23,
protein: 6.0,
iron: '7%',
},
{
name: 'Cupcake',
calories: 305,
fat: 3.7,
carbs: 67,
protein: 4.3,
iron: '8%',
},
{
name: 'Gingerbread',
calories: 356,
fat: 16.0,
carbs: 49,
protein: 3.9,
iron: '16%',
},
{
name: 'Jelly bean',
calories: 375,
fat: 0.0,
carbs: 94,
protein: 0.0,
iron: '0%',
},
{
name: 'Lollipop',
calories: 392,
fat: 0.2,
carbs: 98,
protein: 0,
iron: '2%',
},
{
name: 'Honeycomb',
calories: 408,
fat: 3.2,
carbs: 87,
protein: 6.5,
iron: '45%',
},
{
name: 'Donut',
calories: 452,
fat: 25.0,
carbs: 51,
protein: 4.9,
iron: '22%',
},
{
name: 'KitKat',
calories: 518,
fat: 26.0,
carbs: 65,
protein: 7,
iron: '6%',
},
],
}
},
})
.my-border td:nth-child(1) {
border-left: 5px solid red;
}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vuetify#2.3.2/dist/vuetify.min.css">
<script src="https://cdn.jsdelivr.net/npm/babel-polyfill/dist/polyfill.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue#2.x/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify#2.3.2/dist/vuetify.min.js"></script>
<div id="app">
<v-app id="inspire">
<v-data-table
:headers="headers"
:items="desserts"
:items-per-page="5"
class="elevation-1"
>
<template slot="item" slot-scope="data">
<tr :class="data.item.calories % 2 === 0 ? 'my-border': ''">
<td v-for="(item, index) in Object.values(data.item)" :key="index" >{{item}}</td>
</tr>
</template>
</v-data-table>
</v-app>
</div>
Uses the slot=item.name.
new Vue({
el: '#app',
vuetify: new Vuetify(),
data () {
return {
headers: [
{
text: 'Dessert (100g serving)',
align: 'start',
sortable: false,
value: 'name',
},
{ text: 'Calories', value: 'calories' },
{ text: 'Fat (g)', value: 'fat' },
{ text: 'Carbs (g)', value: 'carbs' },
{ text: 'Protein (g)', value: 'protein' },
{ text: 'Iron (%)', value: 'iron' },
],
desserts: [
{
name: 'Frozen Yogurt',
calories: 159,
fat: 6.0,
carbs: 24,
protein: 4.0,
iron: '1%',
},
{
name: 'Ice cream sandwich',
calories: 237,
fat: 9.0,
carbs: 37,
protein: 4.3,
iron: '1%',
},
{
name: 'Eclair',
calories: 262,
fat: 16.0,
carbs: 23,
protein: 6.0,
iron: '7%',
},
{
name: 'Cupcake',
calories: 305,
fat: 3.7,
carbs: 67,
protein: 4.3,
iron: '8%',
},
{
name: 'Gingerbread',
calories: 356,
fat: 16.0,
carbs: 49,
protein: 3.9,
iron: '16%',
},
{
name: 'Jelly bean',
calories: 375,
fat: 0.0,
carbs: 94,
protein: 0.0,
iron: '0%',
},
{
name: 'Lollipop',
calories: 392,
fat: 0.2,
carbs: 98,
protein: 0,
iron: '2%',
},
{
name: 'Honeycomb',
calories: 408,
fat: 3.2,
carbs: 87,
protein: 6.5,
iron: '45%',
},
{
name: 'Donut',
calories: 452,
fat: 25.0,
carbs: 51,
protein: 4.9,
iron: '22%',
},
{
name: 'KitKat',
calories: 518,
fat: 26.0,
carbs: 65,
protein: 7,
iron: '6%',
},
],
}
},
})
.my-border {
border-left: 5px solid red;
}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vuetify#2.3.2/dist/vuetify.min.css">
<script src="https://cdn.jsdelivr.net/npm/babel-polyfill/dist/polyfill.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue#2.x/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify#2.3.2/dist/vuetify.min.js"></script>
<div id="app">
<v-app id="inspire">
<v-data-table
:headers="headers"
:items="desserts"
:items-per-page="5"
class="elevation-1"
>
<template slot="item.name" slot-scope="data">
<div :class="data.item.calories % 2 === 0 ? 'my-border': ''">{{data.item.name}}</div>
</template>
</v-data-table>
</v-app>
</div>
Use the item slot template...
<template #item="{ item }">
<tr :style="showBorder(item)">
<td v-for="(col,key) in item" :key="key">
{{ col }}
</td>
</tr>
</template>
And a method to determine when to show the border...
methods: {
showBorder(item) {
if (item.name === "Eclair") {
return {borderLeft:'thick solid hsl(0, 100%, 50%)'}
}
},
},
Codeply

Vuetify Expandable Data Table: Expand row position

I'am experimenting with the expandable data table in Vuetify: Vuetify docs
We can use the <template v-slot:expanded-item="{ headers }"> template to customize the expanded item.
I want to show a simple-table in the expandable slot for each row. Currently I have managed to include this, but the column for the simple-table is within the header columns of the data-table.
How can i make the simple-table use more than one column of the data-table?
EDIT: Working codepen: https://codepen.io/5less/pen/QWWvYEw
I've added fixes to the above logic you are trying
Find the working codepen here: https://codepen.io/chansv/pen/yLLbZWo?editors=1010
<div id="app">
<v-app id="inspire">
<v-data-table
:headers="headers"
:items="desserts"
:single-expand="singleExpand"
:expanded.sync="expanded"
item-key="name"
show-expand
class="elevation-1"
>
<template v-slot:top>
<v-toolbar flat color="white">
<v-toolbar-title>Expandable Table</v-toolbar-title>
<v-spacer></v-spacer>
<v-switch v-model="singleExpand" label="Single expand" class="mt-2"></v-switch>
</v-toolbar>
</template>
<template v-slot:expanded-item="{ headers }">
<td :colspan="headers.length">
<v-simple-table>
<template v-slot:default>
<thead>
<tr>
<th>Dessert (400g serving)</th>
<th>Calories</th>
<th>Fat</th>
<th>Carbs</th>
<th>Protein</th>
<th>Iron</th>
</tr>
</thead>
<tbody>
<tr v-for="dessert in desserts" :key="dessert.name">
<td>{{ dessert.name }}</td>
<td>{{ dessert.calories * 4 }}</td>
<td>{{ dessert.fat * 4 }}</td>
<td>{{ dessert.carbs * 4 }}</td>
<td>{{ dessert.protein * 4 }}</td>
<td>{{ '4%' }}</td>
</tr>
</tbody>
</template>
</v-simple-table>
</td>
</template>
</v-data-table>
</v-app>
</div>
new Vue({
el: '#app',
vuetify: new Vuetify(),
data () {
return {
expanded: [],
singleExpand: false,
headers: [
{
text: 'Dessert (100g serving)',
align: 'left',
sortable: false,
value: 'name',
},
{ text: 'Calories', value: 'calories' },
{ text: 'Fat (g)', value: 'fat' },
{ text: 'Carbs (g)', value: 'carbs' },
{ text: 'Protein (g)', value: 'protein' },
{ text: 'Iron (%)', value: 'iron' },
{ text: '', value: 'data-table-expand' },
],
desserts: [
{
name: 'Frozen Yogurt',
calories: 159,
fat: 6.0,
carbs: 24,
protein: 4.0,
iron: '1%',
},
{
name: 'Ice cream sandwich',
calories: 237,
fat: 9.0,
carbs: 37,
protein: 4.3,
iron: '1%',
},
{
name: 'Eclair',
calories: 262,
fat: 16.0,
carbs: 23,
protein: 6.0,
iron: '7%',
},
{
name: 'Cupcake',
calories: 305,
fat: 3.7,
carbs: 67,
protein: 4.3,
iron: '8%',
},
{
name: 'Gingerbread',
calories: 356,
fat: 16.0,
carbs: 49,
protein: 3.9,
iron: '16%',
},
{
name: 'Jelly bean',
calories: 375,
fat: 0.0,
carbs: 94,
protein: 0.0,
iron: '0%',
},
{
name: 'Lollipop',
calories: 392,
fat: 0.2,
carbs: 98,
protein: 0,
iron: '2%',
},
{
name: 'Honeycomb',
calories: 408,
fat: 3.2,
carbs: 87,
protein: 6.5,
iron: '45%',
},
{
name: 'Donut',
calories: 452,
fat: 25.0,
carbs: 51,
protein: 4.9,
iron: '22%',
},
{
name: 'KitKat',
calories: 518,
fat: 26.0,
carbs: 65,
protein: 7,
iron: '6%',
},
],
}
},
})

Deleting the selected row on data table Vuetify

I am using a data-table in vuetify. I am using v-checkbox. I want to delete the selected item from v-checkbox using a button click. I have delete button at the bottom of the data table. So when a user clicks at the delete button the selected row in the data table should be deleted. Any ideas how to do it?
<script>
export default {
data () {
return {
props:[],
selected: [],
headers: [
{
text: 'Name',
align: 'left',
sortable: true,
value: 'name'
},
{ text: 'Organisation', value: 'organisation' },
{ text: 'Supplier', value: 'supplier' },
{ text: 'Created By', value: 'createdBy' },
{ text: 'Updated By', value: 'updatedBy' },
],
projects: [
{
name: 'test',
organisation: 'test',
supplier: 'test',
createdBy: 'test',
updatedBy: 'test'
},
{
name: 'Ice cream sandwich',
calories: 237,
fat: 9.0,
carbs: 37,
protein: 4.3,
iron: '1%'
},
{
name: 'Eclair',
calories: 262,
fat: 16.0,
carbs: 23,
protein: 6.0,
iron: '7%'
},
{
name: 'Cupcake',
calories: 305,
fat: 3.7,
carbs: 67,
protein: 4.3,
iron: '8%'
},
{
name: 'Gingerbread',
calories: 356,
fat: 16.0,
carbs: 49,
protein: 3.9,
iron: '16%'
},
{
name: 'Jelly bean',
calories: 375,
fat: 0.0,
carbs: 94,
protein: 0.0,
iron: '0%'
},
{
name: 'Lollipop',
calories: 392,
fat: 0.2,
carbs: 98,
protein: 0,
iron: '2%'
},
{
name: 'Honeycomb',
calories: 408,
fat: 3.2,
carbs: 87,
protein: 6.5,
iron: '45%'
},
{
name: 'Donut',
calories: 452,
fat: 25.0,
carbs: 51,
protein: 4.9,
iron: '22%'
},
{
name: 'KitKat',
calories: 518,
fat: 26.0,
carbs: 65,
protein: 7,
iron: '6%'
}
]
}
},
methods: {
deleteProject
{
// delete funtion here
},
liveProject()
{
alert("live");
},
closeProject()
{
alert("close");
},
}
}
</script>
<template>
<div>
<v-toolbar flat color="white">
<v-toolbar-title>Manage Projects</v-toolbar-title>
{{ props }}
</v-toolbar>
<v-data-table
v-model="props"
:headers="headers"
:items="projects"
item-key="name"
select-all
class="elevation-1"
>
<template slot="items" slot-scope="props">
<td>
<v-checkbox
v-model="props.selected"
primary
hide-details
></v-checkbox>
</td>
<td>{{ props.item.name }}</td>
<td class="text-xs-left">{{ props.item.organisation }}</td>
<td class="text-xs-left">{{ props.item.supplier }}</td>
<td class="text-xs-left">{{ props.item.createdBy }}</td>
<td class="text-xs-left">{{ props.item.updatedBy }}</td>
</template>
</v-data-table>
<div class="text-xs-center pt-2">
<v-btn color="primary" #click="deleteProject">Delete</v-btn>
<v-btn color="primary" #click="liveProject">Make Live</v-btn>
<v-btn color="primary" #click="closeProject">Close</v-btn>
</div>
</div>
</template>
Here is the code for deleting selected rows from your data table.
Check the example below.
Codepen link to your solution
Template=>
<div id="app">
<v-app id="inspire">
<v-data-table
v-model="selected"
:headers="headers"
:items="desserts"
item-key="name"
select-all
class="elevation-1"
>
<template slot="items" slot-scope="props">
<td>
<v-checkbox
v-model="props.selected"
primary
hide-details
></v-checkbox>
</td>
<td>{{ props.item.name }}</td>
<td class="text-xs-right">{{ props.item.calories }}</td>
<td class="text-xs-right">{{ props.item.fat }}</td>
<td class="text-xs-right">{{ props.item.carbs }}</td>
<td class="text-xs-right">{{ props.item.protein }}</td>
<td class="text-xs-right">{{ props.item.iron }}</td>
</template>
</v-data-table>
<div>
<v-btn color="primary" #click="deleteItem">Delete</v-btn>
</div>
</v-app>
</div>
Script =>
new Vue({
el: '#app',
data () {
return {
selected: [],
headers: [
{
text: 'Dessert (100g serving)',
align: 'left',
sortable: false,
value: 'name'
},
{ text: 'Calories', value: 'calories' },
{ text: 'Fat (g)', value: 'fat' },
{ text: 'Carbs (g)', value: 'carbs' },
{ text: 'Protein (g)', value: 'protein' },
{ text: 'Iron (%)', value: 'iron' }
],
desserts: [
{
name: 'Frozen Yogurt',
calories: 159,
fat: 6.0,
carbs: 24,
protein: 4.0,
iron: '1%'
},
{
name: 'Ice cream sandwich',
calories: 237,
fat: 9.0,
carbs: 37,
protein: 4.3,
iron: '1%'
},
{
name: 'Eclair',
calories: 262,
fat: 16.0,
carbs: 23,
protein: 6.0,
iron: '7%'
},
{
name: 'Cupcake',
calories: 305,
fat: 3.7,
carbs: 67,
protein: 4.3,
iron: '8%'
},
{
name: 'Gingerbread',
calories: 356,
fat: 16.0,
carbs: 49,
protein: 3.9,
iron: '16%'
},
{
name: 'Jelly bean',
calories: 375,
fat: 0.0,
carbs: 94,
protein: 0.0,
iron: '0%'
},
{
name: 'Lollipop',
calories: 392,
fat: 0.2,
carbs: 98,
protein: 0,
iron: '2%'
},
{
name: 'Honeycomb',
calories: 408,
fat: 3.2,
carbs: 87,
protein: 6.5,
iron: '45%'
},
{
name: 'Donut',
calories: 452,
fat: 25.0,
carbs: 51,
protein: 4.9,
iron: '22%'
},
{
name: 'KitKat',
calories: 518,
fat: 26.0,
carbs: 65,
protein: 7,
iron: '6%'
}
]
}
},
methods: {
deleteItem () {
if(confirm('Are you sure you want to delete this item?')){
for(var i = 0; i <this.selected.length; i++){
const index = this.desserts.indexOf(this.selected[i]);
this.desserts.splice(index, 1);
}
}
}
}
})
deleteProject(item_name){
this.projects.splice(this.projects.findIndex(e=> e.name == item_name),1)
}
// JS splice method for remove items from an array.
// JS findIndex method for find the index of the element which you want to delete.
I had a similar issue yesterday but with jquery. Now with vuejs, it is actually simpler I guess with model binding so that all the selected rows will be pushed to a data property. Then on clicking delete, loop through all the selected id's or keys and remove them from your store or by calling a backend api or your data property like you've done here E.g.
data: () => ({
selected: [],
projects: {/*...content in here */},
});
methods: {
delete() {
this.selected.forEach(function(project) { // project here is just the index of the selected in the projects array
projects.splice(project, 1);
});
this.selected = []; // don't forget to empty selected
}
}
If the Data table is bound to a store's array of objects :
We can also use map to get the index of the object in a store array and remove it using:
Mutation
REMOVE_OBJECT_FROM_ARRAY: (state, payload) => {
let i = state.someArrayofObjects.map(item => item.id).indexOf(payload.id);
state.someArrayofObjects.splice(i, 1);
}
Here, the id is the id passed with the payload to the MUTATION, we can also pass only the id as the whole payload. In that case, we can do something like:
REMOVE_OBJECT_FROM_ARRAY: (state, payload) => {
let i = state.someArrayofObjects.map(item => item.id).indexOf(payload);
state.someArrayofObjects.splice(i, 1);
}

How to maintain original array order of locally scoped item array?

I am trying to display the values from an array of objects into the DataTable in two different pages based on condition, for example, **If the country is the USA then display it on 1st page or if the country is Sweden then display it in another page ** and when I try to read the index it is showing wrong index value .
<div id="app">
<v-app id="inspire">
<v-data-table
v-model="selected"
v-bind:headers="headers"
v-bind:items="items"
select-all
v-bind:pagination.sync="pagination"
item-key="name"
class="elevation-1"
>
<template slot="headers" slot-scope="props">
<tr>
<th v-for="header in props.headers" :key="header.text"
:class="['column sortable', pagination.descending ? 'desc' : 'asc',
header.value === pagination.sortBy ? 'active' : '']"
#click="changeSort(header.value)"
>
<v-icon>arrow_upward</v-icon>
{{ header.text }}
</th>
</tr>
</template>
<template slot="items" slot-scope="props">
<tr :active="props.selected" v-if="props.item.name=='USA'">
<td>{{ props.item.name }} {{props.index}}</td>
<td class="text-xs-right">{{ props.item.calories }}</td>
<td class="text-xs-right">{{ props.item.fat }}</td>
<td class="text-xs-right">{{ props.item.carbs }}</td>
</tr>
</template>
</v-data-table>
</v-app>
</div>
Here is the Java Script:-
new Vue({
el: '#app',
data () {
return {
pagination: {
sortBy: 'name'
},
selected: [],
headers: [
{
text: 'Country',
align: 'left',
value: 'name'
},
{ text: 'Calories', value: 'calories' },
{ text: 'Fat (g)', value: 'fat' },
{ text: 'Carbs (g)', value: 'carbs' },
],
items: [
{
value: false,
name: 'USA',
calories: 159,
fat: 6.0,
carbs: 24,
},
{
value: false,
name: 'USA',
calories: 237,
fat: 9.0,
carbs: 37,
protein: 4.3,
sodium: 129,
calcium: '8%',
iron: '1%'
},
{
value: false,
name: 'Sweden',
calories: 262,
fat: 16.0,
carbs: 23,
protein: 6.0,
sodium: 337,
calcium: '6%',
iron: '7%'
},
{
value: false,
name: 'Sweden',
calories: 305,
fat: 3.7,
carbs: 67,
protein: 4.3,
sodium: 413,
calcium: '3%',
iron: '8%'
},
{
value: false,
name: 'Sweden',
calories: 356,
fat: 16.0,
carbs: 49,
protein: 3.9,
sodium: 327,
calcium: '7%',
iron: '16%'
},
{
value: false,
name: 'Sweden',
calories: 375,
fat: 0.0,
carbs: 94,
protein: 0.0,
sodium: 50,
calcium: '0%',
iron: '0%'
},
{
value: false,
name: 'Sweden',
calories: 392,
fat: 0.2,
carbs: 98,
protein: 0,
sodium: 38,
calcium: '0%',
iron: '2%'
},
{
value: false,
name: 'Sweden',
calories: 408,
fat: 3.2,
carbs: 87,
protein: 6.5,
sodium: 562,
calcium: '0%',
iron: '45%'
},
{
value: false,
name: 'USA',
calories: 452,
fat: 25.0,
carbs: 51,
protein: 4.9,
sodium: 326,
calcium: '2%',
iron: '22%'
},
{
value: false,
name: 'USA',
calories: 518,
fat: 26.0,
carbs: 65,
protein: 7,
sodium: 54,
calcium: '12%',
iron: '6%'
}
]
}
},
methods: {
toggleAll () {
if (this.selected.length) this.selected = []
else this.selected = this.items.slice()
},
changeSort (column) {
if (this.pagination.sortBy === column) {
this.pagination.descending = !this.pagination.descending
} else {
this.pagination.sortBy = column
this.pagination.descending = false
}
}
}
})
so, in this case, the index should be 0 1 8 9 but I am getting 0 1 2 3 and when I use hide action the index I am getting is 6 7 8 9
Can someone tell me how should I get correct index values
Use this {{items.indexOf(props.item)}} instead of {{props.index}} to get the right index of item