Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bootstrap Modal Hide from VUE method

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">
              &times;
            </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.

like image 513
Carlos Sosa Avatar asked May 16 '19 23:05

Carlos Sosa


4 Answers

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">&times;</span>
</button>

Then create a method to close the modal:

closeModal() {
   document.getElementById('close').click();
},
like image 167
Dan Stoian Avatar answered Sep 21 '22 05:09

Dan Stoian


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 image 44
David SK Avatar answered Sep 21 '22 05:09

David SK


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();
like image 30
abdelgrib Avatar answered Sep 20 '22 05:09

abdelgrib


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.

like image 29
ittus Avatar answered Sep 22 '22 05:09

ittus