Bootstrap Modal Hide from VUE method
Solution 1
If you are using boostrap, you need to call the hide an show methods from it, because modal api create html elements on the fly (as the dark background)
I recommend to create a save method instead of call the $emit, where you can call the modal hide method before emit the save signal.
<script>
import $ from 'jquery'
export default {
name: "CreateTodo",
props: ["mode", "title", "todo"],
ref: "createTodoModal",
mounted() {
if (this.mode == "create") {
this.title = "Create Todo";
}
},
methods: {
save() {
$('#ModalId').modal('hide')
this.$emit('save')
}
}
};
</script>
showModal is not needed in this case.
Solution 2
Add an id to the close X button"
<button type="button" class="close" data-dismiss="modal" aria-label="Close" id="close">
<span aria-hidden="true">×</span>
</button>
Then create a method to close the modal:
closeModal() {
document.getElementById('close').click();
},
Solution 3
Like @Dan Stoian reply, you can use ref in vue.js :
<button ref="Close" type="button" data-dismiss="modal" ...>
...
</button>
And in your handler
this.$refs.Close.click();
Solution 4
You might use v-if to show/hide modal
In your component:
<div v-if="showModal">
<div id="todoModal" class="modal fade" role="dialog">
...
</div>
</div>
and set showModal
to true/false to show/hide component respectively.
Solution 5
you can use this npm package
npm i vue-js-modal
https://www.npmjs.com/package/vue-js-modal
Your code should then be modified in this way:
<template>
<modal :name="'edit-modal'+id" height="auto">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Edit {{ mName }}</h5>
<button type="button" class="close" @click="hideEditModal(id)">
<span aria-hidden="true">×</span>
</button>
</div>
<form action="/user/update" method="patch" @submit.prevent="updateAssistant">
<div class="modal-body">
<div class="position-relative form-group">
<label for="exampleAddress" class="">Full name</label><input name="name" v-model="editName" id="exampleAddress" placeholder="FullName" type="text" class="form-control">
<div v-if="errors.has('editName')" class="alert alert-danger">
{{ errors.first('editName') }}
</div>
</div>
<div class="position-relative form-group">
<label for="exampleEmail11" class="">Email</label><input name="email" v-model="editEmail" id="exampleEmail11" placeholder="email" type="email" class="form-control">
<div v-if="errors.has('editEmail')" class="alert alert-danger">
{{ errors.first('editEmail') }}
</div>
</div>
<div class="position-relative form-group">
<label for="examplePassword11" class="">Change Password</label><input name="password" v-model="editPassword" id="examplePassword11" placeholder="password" type="password" class="form-control">
<div v-if="errors.has('password')" class="alert alert-danger">
{{ errors.first('password') }}
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" @click="hideEditModal(id)">Close</button>
<button type="submit" class="btn btn-primary">Save changes</button>
</div>
<span class="loader" v-if="this.loading" style="position: absolute; bottom: 0.515rem; left: 20px;">
<span class="ball-clip-rotate">
<div style=" border:1px solid #000;"></div>
</span>
</span>
</form>
</modal>
import Errors from '../../Errors.js'
export default {
name: 'AssistantEditModalComponent',
props: [
'mEmail',
'mName',
'id'
],
data () {
return {
editPassword: null,
disabled: false,
errors: Errors,
loading: false
}
},
methods: {
hideEditModal(id) {
this.$modal.hide('edit-modal'+id);
},
setData() {
this.editName = this.mName
this.editEmail = this.mEmail
},
updateAssistant() {
this.disabled = true;
this.loading = true;
const form = {
editName: this.mName,
editEmail: this.mEmail,
password: this.editPassword
}
axios.patch('/user/update/'+this.id, form)
.then((response) => {
this.disabled = false
this.loading = false
this.hideEditModal(this.id)
this.alert(response)
})
.catch((err) => {
this.disabled = false
this.loading = false
Errors.fill(err.response.data.errors)
})
},
alert(response) {
swal(response.data.username, response.data.message, 'success')
},
},
computed: {
editName: {
get: function() {
return this.mName
},
set: function(value) {
this.$emit('update:mName', value);
}
},
editEmail: {
get: function() {
return this.mEmail
},
set: function(value) {
this.$emit('update:mEmail', value);
}
}
}}
Carlos Sosa
Updated on June 16, 2022Comments
-
Carlos Sosa almost 2 years
I have a vuejs component that displays a modal dialog with a small form inside. When the form is submitted I would like to hide the Modal but cannot figure out how to do it. When submitted the form calls a method in the parent.
Here is the component code
<template> <div> <div id="todoModal" class="modal fade" role="dialog"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <h4 class="modal-title">{{ title }}</h4> <button type="button" class="close" data-dismiss="modal"> × </button> </div> <div class="modal-body"> <form id="todoForm" @submit.prevent="$emit('save')"> <div class="form-group"> <label for="name">Todo name</label> <input id="name" v-model="todo.name" type="text" class="form-control" aria-describedby="nameHelp" placeholder="Enter Todo Name" /> <small id="nameHelp" class="form-text text-muted" >Enter your todo's name</small > </div> </form> </div> <div class="modal-footer"> <button class="btn btn-primary mr-4" type="submit" form="todoForm"> <span v-if="mode == 'create'">Create</span> <span v-if="mode == 'update'">Update</span> </button> <button type="button" class="btn btn-danger mr-auto" data-dismiss="modal" @click=" $parent.showModal = false; $parent.getTodos(); " > Cancel </button> </div> </div> </div> </div> </div> </template> <script> export default { name: "CreateTodo", props: ["mode", "title", "todo", "showModal"], ref: "createTodoModal", mounted() { if (this.mode == "create") { this.title = "Create Todo"; } }, methods: {} }; </script> <style scoped></style>
And here is my APP.js file
<template> <div id="app" class="container mt-5"> <router-view ref="createtodo" class="CreateTodo" name="a" :todo="todo" :title="title" :mode="mode" :show-modal="showModal" @save="saveTodo" ></router-view> </div> </template> <script> import { APIService } from "./APIServices"; const apiService = new APIService(); export default { name: "App", data: function() { return { mode: "create", title: "Create Todo", todo: {}, todos: [], numberOfTodos: 0, showModal: false }; }, mounted: function() { this.getTodos(); }, methods: { saveTodo: function() { if (this.mode == "create") { apiService.createTodo(this.todo).then( result => { if (result.status === 200) { this.todo = result.data; this.getTodos(); } }, error => {} ); this.showModal = false; // this.$refs.createtodo.$refs.todoModal } else if (this.mode == "update") { apiService.updateTodo(this.todo).then( result => { this.getTodos(); }, error => {} ); this.showModal = false; } else if (this.mode == "update") { apiService.updateTodo(this.todo).then( result => { this.showModal = false; this.getTodos(); }, error => {} ); } }, } }; </script> <style lang="scss"> </style>
I tried using the ref to reference the Modal from APP.js but it does not work.
-
David SK about 5 yearsReview your property "showModal" It is not used to show/hide something. without bootstrap v-show directive could help.
-
Carlos Sosa about 5 yearsIt works, but the modal's dark background does not go away when the modal hides.
-
-
Carlos Sosa about 5 yearsHi Ittus.. Thanks for the suggestion. I tried it and it does work, however when the modal hides the modal's background does not go away,
-
David SK about 5 yearsIf you are using Bootstrap, you need to hide/show with boostrap methods.
-
ittus about 5 yearsThis might help stackoverflow.com/questions/50168312/…