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.
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();
},
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.
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();
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With