hi i am doing crud in vuetify 3 and for create form i am using v-dailog, i wanted to close v-dailog once form save data to server successfully. i have used composable to handle my all logics. let me share my code.
My component file
RoleOperations.vue
<template>
<v-dialog max-width="800">
<template v-slot:activator="{ props: activatorProps }">
<v-btn
v-bind="activatorProps"
:text="btnTitle"
@click="getAllPermissions(roleId)"
></v-btn>
</template>
<template v-slot:default="{ isActive }">
<v-card :title="modalTitle">
<template v-slot:text>
<div v-if="loading" class=" d-flex justify-center">
<v-progress-circular indeterminate></v-progress-circular>
</div>
<v-form v-else @submit.prevent="handleSubmit(roleId)">
<v-row>
<v-col cols="12">
<v-text-field
v-model="form.name"
:error-messages="errorMessages.name"
autofocus
label="Role Name"
type="text"
placeholder="Administrator Role"
/>
</v-col>
<v-col cols="12">
<div class="d-flex justify-space-between">
<h5>Role Permissions</h5>
<v-checkbox v-model="isSelectAllPermissions" @update:model-value="selectAllPermissions" label="Select All"></v-checkbox>
</div>
<v-container>
<v-row no-gutters>
<v-col v-for="permission in lstPermissions" :key="permission.id" cols="3">
<v-checkbox :value="permission.id" :label="permission.name" v-model="form.permissions"></v-checkbox>
</v-col>
</v-row>
<v-row no-gutters>
<v-col class="text-sm text-error">
{{ errorMessages.permissions }}
</v-col>
</v-row>
</v-container>
</v-col>
</v-row>
<v-row>
<v-col cols="12">
<v-btn
:text="roleId == 0 ? 'save':'update'"
variant="elevated"
type="submit"
class="mr-2"
:loading="formLoading"
>
<template v-slot:loader><v-progress-circular indeterminate></v-progress-circular> Save</template>
</v-btn>
<v-btn
text="Cancel"
variant="tonal"
@click="isActive.value = false"
></v-btn>
</v-col>
</v-row>
</v-form>
</template>
</v-card>
</template>
</v-dialog>
</template>
<script setup lang="ts">
import { useRoleOperations } from '@/composable/useRoleOperations';
const props = defineProps<{
btnTitle: string,
modalTitle:string,
roleId:number
}>()
const {
lstPermissions,
loading,
getAllPermissions,
form,
errorMessages,
handleSubmit,
formLoading,
selectAllPermissions,
isSelectAllPermissions
} = useRoleOperations();
</script>
My composeable file
useRoleOperations.ts
import { IPermissionsList, IRole } from "@/Interfaces/IRole";
import { fetchAllPermissions, fetchRoleByID, saveRole, updateRole } from "@/services/RolesService";
import { toast } from 'vue3-toastify';
export function useRoleOperations (){
const lstPermissions = ref<IPermissionsList>([]);
const loading = ref<boolean>(false);
const formLoading = ref<boolean>(false);
const isSelectAllPermissions = ref<boolean>(false);
const form = ref<IRole>({
name:'',
permissions:[]
});
const selectAllPermissions = () => {
if(isSelectAllPermissions.value == true){
isSelectAllPermissions.value = true;
form.value.permissions = lstPermissions.value.map(({id}) => id);
}
if(isSelectAllPermissions.value == false){
form.value.permissions = []
isSelectAllPermissions.value = false;
}
}
const errorMessages = ref<[name:string, permissions: string]>([]);
const getAllPermissions = (id:number) => {
form.value.name= '';
form.value.permissions=[];
loading.value = true;
//get all permissions
fetchAllPermissions().then((res) => {
lstPermissions.value = res.data.data
//get selected permissions in role edit case
if(id != 0){
fetchRoleByID(id).then((res) => {
let data = res.data.data;
form.value.name = data.name;
form.value.permissions = data.permissions.map(({id}) => id);
if(form.value.permissions.length == lstPermissions.value.length){
isSelectAllPermissions.value = true;
}
}).catch((err) => {
toast.error(err.message)
loading.value = false;
})
}
loading.value = false;
}).catch((err) => {
toast.error(err.message)
loading.value = false;
})
}
const handleSubmit = (id:number) => {
formLoading.value = true;
if(id == 0){
saveRole(form.value).then((res) => {
formLoading.value = false;
toast.success(res.data.message)
})
.catch((err) => {
if(err.response.status == "422"){
errorMessages.value = err.response.data.errors
formLoading.value = false;
}else if(err.response.status == "401"){
toast.error(err.response.data.message);
formLoading.value = false;
errorMessages.value = ['','']
}else{
toast.error(err.message)
formLoading.value = false;
}
})
}else{
updateRole(id,form.value).then((res) => {
formLoading.value = false;
toast.success(res.data.message)
})
.catch((err) => {
if(err.response.status == "422"){
errorMessages.value = err.response.data.errors
formLoading.value = false;
}else if(err.response.status == "401"){
toast.error(err.response.data.message);
formLoading.value = false;
errorMessages.value = ['','']
}else{
toast.error(err.message)
formLoading.value = false;
}
})
}
// here i wanted to close V-DAILOG programatically
}
return {
lstPermissions,
loading,
getAllPermissions,
selectAllPermissions,
handleSubmit,
errorMessages,
isSelectAllPermissions,
formLoading,
form
}
}
looking forward for help.
isActive
slot prop controls the dialog. You are already using it to close the dialog with the cancel button. Simply pass isActive
as another parameter to your submit function so you can set it to false.
<template v-slot:default="{ isActive }">
...
<v-form v-else @submit.prevent="handleSubmit(roleId, isActive)">
const handleSubmit = (id:number, isActive:Ref<boolean>) => {
...
isActive.value = false
}
If that doesn't work, change the submit to call a local function that calls your composable as the first line and set isActive to false as the next line.