Bootstrap V5 manually call a modal myModal.show() not working (vanilla javascript)

Viewed 67393

whats the correct way to manually call a modal in bootstrap 5?

i want to show the modal when page is open. i tried this:

my modal

<div class="modal fade" id="myModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
        ... 
        ... 
        ... 
    </div>
  </div>
</div>

my script is

var myModal = document.getElementById('myModal');
document.onreadystatechange = function() {
   
    myModal.show();
}

but got this error in console log:

 myModal.show is not a function
    at HTMLDocument.document.onreadystatechange
8 Answers

The modal plugin toggles your hidden content on demand, via data attributes or JavaScript. It also adds .modal-open to the to override default scrolling behavior and generates a .modal-backdrop to provide a click area for dismissing shown modals when clicking outside the modal. [source]

How to use via Vanilla JavaScript

Create a modal with a single line of JavaScript:

var myModal = new bootstrap.Modal(document.getElementById('myModal'), options)

source

A quick example:

var myModal = new bootstrap.Modal(document.getElementById("exampleModal"), {});
document.onreadystatechange = function () {
  myModal.show();
};
<!DOCTYPE html>
<html lang="en">
  <head>

    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1, shrink-to-fit=no"
    />


    <link
      rel="stylesheet"
      href="https://stackpath.bootstrapcdn.com/bootstrap/5.0.0-alpha1/css/bootstrap.min.css"
      integrity="sha384-r4NyP46KrjDleawBgD5tp8Y7UzmLA05oM1iAEQ17CSuDqnUK2+k9luXQOfXJCJ4I"
      crossorigin="anonymous"
    />
    <title>Hello, world!</title>
  </head>
  <body>

    <div
      class="modal fade"
      id="exampleModal"
      tabindex="-1"
      role="dialog"
      aria-labelledby="exampleModalLabel"
      aria-hidden="true"
    >
      <div class="modal-dialog">
        <div class="modal-content">
          <div class="modal-header">
            <h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
            <button
              type="button"
              class="close"
              data-dismiss="modal"
              aria-label="Close"
            >
              <span aria-hidden="true">&times;</span>
            </button>
          </div>
          <div class="modal-body">
            ...
          </div>
          <div class="modal-footer">
            <button
              type="button"
              class="btn btn-secondary"
              data-dismiss="modal"
            >
              Close
            </button>
            <button type="button" class="btn btn-primary">Save changes</button>
          </div>
        </div>
      </div>
    </div>

    <!-- JavaScript and dependencies -->
    <script
      src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"
      integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo"
      crossorigin="anonymous"
    ></script>
    <script
      src="https://stackpath.bootstrapcdn.com/bootstrap/5.0.0-alpha1/js/bootstrap.min.js"
      integrity="sha384-oesi62hOLfzrys4LxRF63OJCXdXDipiYWBnvTl9Y9/TRlw5xlKIEHpNyvvDShgf/"
      crossorigin="anonymous"
    ></script>

    <script src="./app.js"></script>
  </body>
</html>

As for your code, you didn't follow the right way to show/toggle a modal in Vanilla JavaScript. Why did you expect myModal.show() to happen while myModal is just a DOM element?

  1. Create a new instace of modal and then call show method(see usage points)
var myModal = new bootstrap.Modal(document.getElementById('exampleModal'))
myModal.show()

enter image description here

ref: https://v5.getbootstrap.com/docs/5.0/components/modal/#options

note: Bootstrap v5 no more uses jquery, instead it uses javascript. lots of changes are there in bootstrap v5, if you are working for a company and willing to use Bootstrap v5 then please go through all the changes.

Based on the javascript code provided by the OP I think the actual goal here is to reach out the component by the DOM element. I have also looked for a way to do this so wanted to share what I have found(or not found).

v4- It was possible and commonly used with the earlier versions. In v4 we could have used it easily with jQuery although the component is initialized by the data attributes and not directly from js.

$('#myModal').modal('show');

v5.0.0-beta2 In the new version, a very promising api example is provided at the docs for another type of component. However, it does not seem to be working currently. (https://getbootstrap.com/docs/5.0/getting-started/javascript/#asynchronous-functions-and-transitions)

var myModal = document.getElementById('myModal')
var modal = bootstrap.Modal.getInstance(myModal) 
console.log(modal) // null

Since all the components are using same basecomponent, one might think that it is possible to get instance of the modal as well as the others like dropdown, collapse, carousel and all by using getInstance api method but it is not possible. At least for the current beta version.

A final note: It is still possible to include jQuery before v5 script and achive this.(https://codepen.io/cadday/pen/Jjbvxvm)

window.onload = function() {
  console.log(jQuery('#myModal').modal('show'));
}

I've also searched for a solution to auto-open the modal on page load and solved it in the following solution. You be able to add an data-auto-open attribute to the normal bootstrap syntax if you want to have it auto-opened. If the attribute is not set, is the modal working in the standard way as well.

I've added also an option to temporarily remove the fade effect if you want to have it open instantly after the page load. To make it happen is it just necessary to use data-auto-open="instant" instead of the empty data-auto-open attribute. After it's closed once and you want to re-open it manually will it have the fade effect again.

The working solution in TypeScript for Bootstrap 5.0.0-Beta3 would be like this:

// @ts-ignore
import { Modal } from 'bootstrap';

window.addEventListener('DOMContentLoaded', (event) => {
    const selector = '[data-auto-open]';
    const modalElement: HTMLElement | null = document.querySelector(selector);

    if (!modalElement) {
        return;
    }

    const mode = modalElement.dataset.autoOpen;
    const fade = modalElement.classList.contains('fade');

    if (fade && mode === 'instant') {
        modalElement.classList.remove('fade');
    }

    const modal = new Modal(modalElement, {});

    if (fade && mode === 'instant') {
        // There's currently a bug in the backdrop when the fade class 
        // will be added directly after the modal was opened to have the
        // close animation
        // modalElement.addEventListener('shown.bs.modal', function (event) {
        modalElement.addEventListener('hidden.bs.modal', function (event) {
            modalElement.classList.add('fade');
        }, {once : true});
    }

    modal.show();
}, {once : true});

The HTML would be the standard one:

<!-- Button trigger modal -->
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModal">
    Demo modal
</button>

<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true" data-auto-open>
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title" id="exampleModalLabel">
                    Example Modal title
                </h5>
                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
            </div>
            <div class="modal-body">
                Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy
                eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-cancel" data-bs-dismiss="modal">
                    Close
                </button>
            </div>
        </div>
    </div>
</div>

[Bootstrap 5]

Plugins can be included individually (using Bootstrap’s individual js/dist/*.js), or all at once using bootstrap.js or the minified bootstrap.min.js (don’t include both).

If you use a bundler (Webpack, Rollup…), you can use /js/dist/*.js files which are UMD ready.

For Example, if you want to import only the Modal plugin from Bootstrap 5 you can do it:

Add the import statement at the top of your js file

import Modal from 'bootstrap/js/dist/modal';

And then show the modal when click on a button element for instance:

const myButton = document.getElementById('my-button-id');
const myModal  = document.getElementById('my-modal-id');

const modal = new Modal(myModal); // Instantiates your modal

myButton.addEventListener('click', () => {
    modal.show(); // shows your modal
});

An easy way to open/show a modal dialog in Bootstrap 5 is to create a link in your HTML to do it (it can be invisible), and then create/trigger a click event on the link.

Here is an example:

A link to open a modal dialog:

<a id=test data-bs-toggle="modal" href="#MODAL-ID"></a>

The JavaScript code to trigger the click event on this link:

triggerEvent(test,'click');

function triggerEvent(el,evName)
    {el.dispatchEvent(new CustomEvent(evName,{}));}

The fastest way to do it

new bootstrap.Modal($('#MyModal')).show();
Related