I have data table with vuetify v-switch inside it. When user click on v-switch it toggle itself. I want to restore it to previous state when user cancels the swal(sweet alert). The switch should revert back to active if it is inactive and vice-versa.
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<v-data-table :headers="headers" :items="users" item-key="pk" :loading="loading" hide-default-footer :items-per-page="i_per_page">
<template v-slot:item.switch="{ item }">
<v-tooltip bottom v-if="item.is_active=='active'">
<template v-slot:activator="{ on, attrs }">
<div v-bind="attrs" v-on="on">
<v-switch :id="String(item.user_id)" :loading='switchLoader' true-value="active" false-value="null" v-model="item.is_active" @click="toggle_status(item.user_id, item.is_active, $event)"></v-switch>
</div>
</template>
<small v-if="item.is_active">Suspend</small>
</v-tooltip>
<v-tooltip bottom v-if="item.is_active=='null'">
<template v-slot:activator="{ on, attrs }">
<div v-bind="attrs" v-on="on">
<v-switch :loading='switchLoader' true-value="active" false-value="null" v-model="item.is_active" @click="toggle_status(item.user_id, item.is_active, $event)"></v-switch>
</div>
</template>
<small>Activate</small>
</v-tooltip>
</template>
</v-data-table>
<script>
methods: {
toggle_status(user_id, value, e) {
console.log(e)
if (value == 'null') {
this.action = '0'
swal.fire({
title: 'Are you sure you want to deactivate user?',
showDenyButton: true,
confirmButtonText: `Deactivate`,
denyButtonText: `Cancel`
}).then(result => {
if (result.isConfirmed) {
this.toggle_user(user_id, value)
} else {
return false
}
})
} else if (value == 'active') {
this.action = '1'
swal.fire({
title: 'Are you sure you want to activate user?',
showDenyButton: true,
confirmButtonText: `Activate`,
denyButtonText: `Cancel`
}).then(result => {
if (result.isConfirmed) {
this.toggle_user(user_id, value)
} else {
return false
}
})
}
}
}
</script>
v-model is basically an abbreviated tag for value and @input.
You need to handle input change for v-switch on your own so you shouldn't use v-model.
Now the bindings of v-model are different for different components. For e.g. Vuetify v-switch component binds v-model to input-value as we can see from the API: https://vuetifyjs.com/en/api/v-switch/#props-input-value
So basically, writing v-model="item.is_active" is internally same as :input-value="item.is_active" @change="item.is_active = $event.target.value"
So you can rewrite your code as :input-value="item.is_active @change="toggle_status(item.user_id, item.is_active, $event)"
(Note you shouldn't use @click event here as it may get triggered before input-value is updated)
You can reset the v-switch if user cancels swal:
const i = this.users.findIndex((user) => user.user_id == user_id);
this.users[i].is_active = e;
swal.fire({
title: 'Are you sure you want to deactivate user?',
showDenyButton: true,
confirmButtonText: `Deactivate`,
denyButtonText: `Cancel`
}).then(result => {
if (result.isConfirmed) {
this.toggle_user(user_id, value)
} else {
const i = this.users.findIndex((user) => user.user_id == user_id);
this.users[i].is_active = e == "active" ? "null" : "active"; // reset is_active if user cancels the swal
}
})
Can you try the following steps?
Remove the v-switch binding (v-model) to item.is_active
On the toggle_status method, get the current value through the event, and change to look like this:
toggle_status: (event) {
const value = event.target.value
console.log('value: ', value)
if (value === 'active') {
... // Insert the same code for the swall calls in here
}
}
And surely, in the <template> you should be doing like this
<v-switch ... @click="toggle_status($event)"></v-switch>