SVE
SVE

Reputation: 1655

Append bootstrap-vue modal to app template

I use bootstrap-vue modal:

In my project codesandbox:

Template:

<template>
  <b-button variant="link" class="btn-remove" @click="removeItemFromOrder(index)">
    Remove item
  </b-button>
</template>

Script generating modal with custom content:

<script>
export default {
  name: "HelloWorld",
  methods: {
    removeItemFromOrder: async function (position) {
        let self = this

        const h = this.$createElement

        const titleVNode = h('div', { domProps: { innerHTML: '<h2>Remove this item?</h2>' } })

        const messageVNode = h('div', { class: ['modal-complete'] }, [

          h('div', {
            domProps: {
              innerHTML:  '<h2>Remove this item?</h2>'+
                          '<span class="popup-meta">'+
                            'Are you sure you want to remove this item?'+
                          '</span>'
            }
          })
        ])


        this.$bvModal.msgBoxConfirm([messageVNode], {
          title: [],
          centered: true,
          modalClass: 'success-popup',
          hideHeader:true,
          footerClass: 'd-flex justify-content-center align-items-center',
          cancelVariant: 'outline-danger',
          okVariant: 'danger',
          okTitle: 'YES',
          cancelTitle: 'NO',
          ststic: false
        })
          .then(async function (result) {
            if (result) {
              self.currentOrder.items.splice(position, 1)
              await self.sync()
            }
          })
          .catch(err => {
            // An error occurred
          })
      },
  }
};
</script>

Now bootstrap modal after open append to body. So, that's why I have a quastion:

How I can append bootstrap-vue modal to #app or another template\ tag?

P.S: only for this.$bvModal.msgBoxConfirm with then ... So as not to create unnecessary methods ... due to amount of popups with diffetent logic

Upvotes: 14

Views: 2115

Answers (2)

Vo Kim Nguyen
Vo Kim Nguyen

Reputation: 1633

It's not posible If you read the code, it just append direct the Modal to the body

https://github.com/bootstrap-vue/bootstrap-vue/blob/dev/src/components/modal/helpers/bv-modal.js#L162

  const div = document.createElement('div')
  document.body.appendChild(div)
  msgBox.$mount(div)

Upvotes: 9

Taylor White
Taylor White

Reputation: 684

I was running into the same issues and came up with a workaround. I'm using a scoped version of bootstrap, where each bootstrap class is prefixed with .bootstrap-scope so that bootstrap styles don't interfere with other things on the page. That means having the modal appended directly to the body wouldn't work, as it wouldn't inherit the bootstrap styles from within .bootstrap-scope (and I can't add the bootstrap-scope class to the body).

I already have jquery loaded, so my solution is to simply capture the $bvModal.show() event by immediately hiding the modal that's newly created and appended to the body (which won't show up correctly) and then appending the modal to the container I want. The catch is that the modal needs to be removed from the custom container when it's hidden, because the show event will recreate it and there will be issues.

show_modal: function(viz) {
    var vm = this;              

    vm.$bvModal.show(vm.modalId); 
    $(`#${vm.modalId}___BV_modal_outer_`).hide(); 

    setTimeout(()=>{
        $(`#${vm.modalId}`).appendTo('#' + vm.containerId); 
        $(`#${vm.modalId}___BV_modal_outer_`).show(200); 
    }, 50); 

}



hide_modal: function() {
    this.$bvModal.hide(this.modalId}); 
    $(`#${this.containerId} .modal`).remove(); 
}

Upvotes: 0

Related Questions