0

Soo, originally I just wanted include a boostrap modal inside a vue component, that I can toggle via an event bus (mitt). Clicking outside the modal should not close it and pressing escape shouldn't either. Using the data toggles <div class="modal hide fade" data-keyboard="false" data-backdrop="static"> should be the solution, but it didn't work. This snippet is exactly what I wanted to achieve, but sets the data-backdrop inside the button that calls the modal not the modal itself. So I'm already confused. Furthermore when removing the jquery reference in the snippet it breaks. So it seems like I need to import jquery to use bootstrap properly in my vue app. I've installed bootstrap and jquery via npm, but how to import it... Sources talk about webpack, but I'm not using webpack right now. <script src=...> does obviously not work in vue and I can't just import it in the <script setup> part. importing it inside main.js didn't seem to work either.

Here is my current code for reference (but it shouldn't really matter):

<script setup>
import { onMounted, inject, reactive } from 'vue';
import { Modal } from 'bootstrap';

const data = reactive({ message: undefined, details: undefined })

let modal;
onMounted(() => {
    modal = new Modal('#errorModal');
})

inject('Events').on('error', function (e) {
    modal.show();
    data.message = e.message;
    data.details = e.details;
})


</script>
<template>
        <div tabindex="-1" id="errorModal" class="modal hide fade in" data-keyboard="false" data-backdrop="static">
            <div class="modal-dialog modal-confirm">
                <div class="modal-content">
                    <div class="modal-header justify-content-center">
                        <h4 style="color: white;">Ooops! TODO: DISABLE ABILITY TO CLICK OF MODAL </h4>
                    </div>
                    <div class="modal-body text-center">
                        <p>{{ data.message || 'UNKNOWN_ERROR' }}</p>
                    </div>
                    <div v-if="data.details" class="modal-footer">
                        <span class="me-auto">{{ data.details }}</span>
                    </div>
                </div>
            </div>
    </div>
</template>

<!-- Design from from https://www.tutorialrepublic.com/codelab.php?topic=bootstrap&file=elegant-error-modal -->
<style>
body {
    font-family: 'Varela Round', sans-serif;
}

.modal-confirm {
    color: #434e65;
    width: 525px;
}

.modal-confirm .modal-content {
    padding: 20px;
    font-size: 16px;
    border-radius: 5px;
    border: none;
}

.modal-confirm .modal-header {
    background: #e85e6c;
    border-bottom: none;
    position: relative;
    text-align: center;
    margin: -20px -20px 0;
    border-radius: 5px 5px 0 0;
    padding: 35px;
}

.modal-confirm h4 {
    text-align: center;
    font-size: 36px;
    margin: 10px 0;
}

.modal-confirm .form-control,
.modal-confirm .btn {
    min-height: 40px;
    border-radius: 3px;
}

.modal-confirm .close {
    position: absolute;
    top: 15px;
    right: 15px;
    color: #fff;
    text-shadow: none;
    opacity: 0.5;
}

.modal-confirm .close:hover {
    opacity: 0.8;
}

.modal-confirm .icon-box {
    color: #fff;
    width: 95px;
    height: 95px;
    display: inline-block;
    border-radius: 50%;
    z-index: 9;
    border: 5px solid #fff;
    padding: 15px;
    text-align: center;
}

.modal-confirm .icon-box i {
    font-size: 58px;
    margin: -2px 0 0 -2px;
}

.modal-confirm.modal-dialog {
    margin-top: 80px;
}

.modal-confirm .btn,
.modal-confirm .btn:active {
    color: #fff;
    border-radius: 4px;
    background: #eeb711 !important;
    text-decoration: none;
    transition: all 0.4s;
    line-height: normal;
    border-radius: 30px;
    margin-top: 10px;
    padding: 6px 20px;
    min-width: 150px;
    border: none;
}

.modal-confirm .btn:hover,
.modal-confirm .btn:focus {
    background: #eda645 !important;
    outline: none;
}

.trigger-btn {
    display: inline-block;
    margin: 100px auto;
}
</style>

By the way should I use import { Modal } from 'bootstrap'; to interact with bootstrap items anyways? I've seen 50 variants to manipulate them. What's the standard way?

1 Answer 1

0

To show or hide a Bootstrap modal with Vue, no need for jQuery, just play on class and style of the .modal element:

  • <div class="modal">...</div> -> the modal is hidden
  • <div class="modal show" style="display: block;">...</div> -> the modal is visible

An example with a showModal ref (but the trigger could be an event bus, or anything else):

<script setup lang="ts">
import { ref } from 'vue'

const showModal = ref(false)
</script>

<template>
  <button @click="showModal = true">Show modal</button>

  <div
    class="modal fade"
    id="exampleModal"
    tabindex="-1"
    aria-labelledby="exampleModalLabel"
    aria-hidden="true"
    :class="{ show: showModal }"
    :style="{ 'background-color': 'rgba(0, 0, 0, .5)', display: showModal ? 'block' : 'none' }"
  >
    <div class="modal-dialog">
      <div class="modal-content">
        <div class="modal-header">
          <h1 class="modal-title fs-5" id="exampleModalLabel">Modal title</h1>
          <button type="button" class="btn-close" aria-label="Close" @click="showModal = false"></button>
        </div>
        <div class="modal-body">
          ...
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-secondary">Close</button>
          <button type="button" class="btn btn-primary">Save changes</button>
        </div>
      </div>
    </div>
  </div>
</template>

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.