Modal not displaying with bulma css

11,750

Solution 1

I ran into this problem this week and I found this link. It contains Official (according to it) Bulma Modal Doc page's javascript code. I copied and reduced it by a line or two and it works for all bulma modals you will have in your code.

Note that this is pretty open code. Ali's answer is ideal route to follow but if you don't want to spend time writing codes for modals, then just copy this segment in your code.

document.addEventListener('DOMContentLoaded', function () {

    // Modals

    var rootEl = document.documentElement;
    var allModals = getAll('.modal');
    var modalButtons = getAll('.modal-button');
    var modalCloses = getAll('.modal-background, .modal-close, .modal-card-head .delete, .modal-card-foot .button');

    if (modalButtons.length > 0) {
        modalButtons.forEach(function (el) {
            el.addEventListener('click', function () {
                var target = document.getElementById(el.dataset.target);
                rootEl.classList.add('is-clipped');
                target.classList.add('is-active');
            });
        });
    }

    if (modalCloses.length > 0) {
        modalCloses.forEach(function (el) {
            el.addEventListener('click', function () {
                closeModals();
            });
        });
    }

    document.addEventListener('keydown', function (event) {
        var e = event || window.event;
        if (e.keyCode === 27) {
            closeModals();
        }
    });

    function closeModals() {
        rootEl.classList.remove('is-clipped');
        allModals.forEach(function (el) {
            el.classList.remove('is-active');
        });
    }

    // Functions

    function getAll(selector) {
        return Array.prototype.slice.call(document.querySelectorAll(selector), 0);
    }
});

Solution 2

Before starting, easy way to open modal should be like this;

yourElem.classList.toggle('is-active')

In my project, I have many modals. So I didn't always want to use like above. Because of this, I have created a basic modal event listener. I know this isn't enough for you. Because there will be other situations to open and close modals.

In this case, you can open and close your modals even you can listen to show and close events.

I used this Mozilla resource to create custom events. For example, you want to create two events called modal:show and modal:close. To make this, you should write some codes like below:

On Show Event

var event = new Event('modal:show')

yourElem.dispatchEvent(event);

On Close Event

var event = new Event('modal:close')

yourElem.dispatchEvent(event);

Now, we can listen to the above events.

An Example to Listen to Show Event

yourElem.addEventListener('modal:show', function() {
    console.log("opened")
})

An Example to Listen to Close Event

yourElem.addEventListener("modal:close", function() {
    console.log("closed")
})

We know how to open and close modal from easy way section. But sometimes users can click the modal background or "X" or Cancel buttons. If so, we need to handle these events. To make this we can use this code

var modalClose = yourelem.querySelectorAll("[data-bulma-modal='close'], 
  .modal-background")

modalClose.forEach(function(e) {
    e.addEventListener("click", function() {

        yourelem.classList.toggle('is-active')

            var event = new Event('modal:close')

            yourelem.dispatchEvent(event);
        })
})

That's all. We know how to open or close a Bulma modal. Even we can listen to their show and close events. Let's make it a little simpler

Creating A BulmaModal Class

class BulmaModal {
    constructor(selector) {
        this.elem = document.querySelector(selector)
        this.close_data()
    }

    show() {
        this.elem.classList.toggle('is-active')
        this.on_show()
    }

    close() {
        this.elem.classList.toggle('is-active')
        this.on_close()
    }

    close_data() {
        var modalClose = this.elem.querySelectorAll("[data-bulma-modal='close'], 
        .modal-background")

        var that = this
        modalClose.forEach(function(e) {
            e.addEventListener("click", function() {

                that.elem.classList.toggle('is-active')

                var event = new Event('modal:close')

                that.elem.dispatchEvent(event);
            })
        })
    }

    on_show() {
        var event = new Event('modal:show')

        this.elem.dispatchEvent(event);
    }

    on_close() {
        var event = new Event('modal:close')

        this.elem.dispatchEvent(event);
    }

    addEventListener(event, callback) {
        this.elem.addEventListener(event, callback)
    }
}

Usage

var btn = document.querySelector("#btn")
var mdl = new BulmaModal("#myModal")

btn.addEventListener("click", function () {
    mdl.show()
})

mdl.addEventListener('modal:show', function() {
    console.log("opened")
})

mdl.addEventListener("modal:close", function() {
    console.log("closed")
})

Let's look at this simple snippet

class BulmaModal {
	constructor(selector) {
		this.elem = document.querySelector(selector)
		this.close_data()
	}
	
	show() {
		this.elem.classList.toggle('is-active')
		this.on_show()
	}
	
	close() {
		this.elem.classList.toggle('is-active')
		this.on_close()
	}
	
	close_data() {
		var modalClose = this.elem.querySelectorAll("[data-bulma-modal='close'], .modal-background")
		var that = this
		modalClose.forEach(function(e) {
			e.addEventListener("click", function() {
				
				that.elem.classList.toggle('is-active')

				var event = new Event('modal:close')

				that.elem.dispatchEvent(event);
			})
		})
	}
	
	on_show() {
		var event = new Event('modal:show')
	
		this.elem.dispatchEvent(event);
	}
	
	on_close() {
		var event = new Event('modal:close')
	
		this.elem.dispatchEvent(event);
	}
	
	addEventListener(event, callback) {
		this.elem.addEventListener(event, callback)
	}
}

var btn = document.querySelector("#btn")
var mdl = new BulmaModal("#myModal")

btn.addEventListener("click", function () {
	mdl.show()
})

mdl.addEventListener('modal:show', function() {
	console.log("opened")
})

mdl.addEventListener("modal:close", function() {
	console.log("closed")
})
<link href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.1/css/bulma.min.css" rel="stylesheet"/>

<div class="modal" id="myModal">
  <div class="modal-background"></div>
  <div class="modal-card">
    <header class="modal-card-head">
      <p class="modal-card-title">Modal title</p>
      <button class="delete" aria-label="close" data-bulma-modal="close"></button>
    </header>
    <section class="modal-card-body">
      <p>There is something here</p>
    </section>
    <footer class="modal-card-foot">
      <button class="button is-success">Save changes</button>
      <button class="button" data-bulma-modal="close">Cancel</button>
    </footer>
  </div>
</div>

<button id="btn">Click active Modal</button>

I hope this answer will help Bulma newbies.

Solution 3

Bulma CSS is a CSS only framework and all the javascript behaviour has to be written manually. That means for a modal all the CSS classes for hiding and showing the modal has been written and you have to just bind the events properly. If you visit the Modal doc page (https://bulma.io/documentation/components/modal/) you can see a No Javascript warning stating that

Bulma does not include any JavaScript interaction. You will have to implement the class toggle yourself.

Just define refs.modalEdicion.open function to add class is-active as per the doc and bind events on close button to remove the same CSS class. Optionally you might wish to bind the event to the overlay element as well if you want to dismiss modal by clicking the overlay.

Here is the desired implementation. https://codepen.io/anon/pen/KRaqxG

Share:
11,750

Related videos on Youtube

Dexter Naru
Author by

Dexter Naru

Updated on June 04, 2022

Comments

  • Dexter Naru
    Dexter Naru over 1 year

    I want to display a modal when a button is clicked but is not working. Here the code:

        <button class="button is-warning is-pulled-right" onclick="refs.modalEdicion.open()">
            <span>Editar</span>
        </button>
        <div class="modal" id="modalEdicion">
            <div class="modal-background"></div>
            <div class="modal-content">
                <p class="image is-4by3">
                <img src="https://bulma.io/images/placeholders/1280x960.png" alt="">
                </p>
            </div>
            <button class="modal-close is-large" aria-label="close"></button>
        </div>