Topic: bug on mdb events (modal tested)
sody priority asked 3 years ago
Expected behavior
hidden.mdb.modal event handler runs once upon modal disposal
using jquery the event handler is bound outside any click event of course to insure it tha handler runs only once!
Actual behavior
when specifiying "hidden.mdb.modal" event handler for some reason if I open the modal, close, open again, close , 3 , 4 ==> the event is fired twice, 3 times and so on
when switching back to "hidden.bs.modal" the functionallity is restored! fires only once
This is a seriuos bug as it leads to bad behaviour!!!
Resources (screenshots, code snippets etc.)
for the test i added a console.log("yea") in the handlerhere you can see (ignore the "2" logged to console) that after i open/close twice and 3 times the log is happening:
as i said interestingly it doesn't behave like that when i switch back to "hidden.bs.modal" event
$('#mymodal').on('hidden.mdb.modal', function (e) {
console.log('yeaa');
});
vs
$('#mymodal').on('hidden.bs.modal', function (e) {
console.log('yeaa');
});
loading the modal is as described in the docs:
function loadModal() {
var myModal = new mdb.Modal(document.getElementById('myModal'), {
keyboard: false
});
myModal.show();
}
I suspect that this code creates multiple Modal objects, what is the safest way to do this? btw: i tried the traditional way and it seems to restore the desired functionallity although i don't know if it supposed and if it loads MDB MODAL:
function loadModal() {
$('#myModal').modal({
show: true,
keyboard: false
});
}
the head of the modal html code is:
<div class="modal fade" id="mymodal" data-mdb-backdrop="static" tabindex="-1" role="dialog"
aria-labelledby="my modal" aria-hidden="true">
<div class="modal-dialog modal-dialog-scrollable modal-xl" role="document">
<div class="modal-content">
the footer has cancel button
<div class="modal-footer">
<button class="btn btn-secondary" id='cancelMyModalBtn' type="button"
data-mdb-dismiss="modal">Cancel</button></div>
Grzegorz Bujański staff answered 3 years ago
Note that this event is bound once to EVENT_HIDDEN_BS_MODAL
. There is no logic anywhere in the code that could bind this event again. Therefore, using on
here instead of one
is correct and is not a bug.
To the modal opening button you added: onclick="loadModal();"
. loadModal()
created a new instance of the Modal class each time when the button is clicked. This means that the constructor that binds the events again was started. What I did was add a condition that checks if the Modal class instance already exists for a given element. This prevents the creation of another instance of the class.
sody priority commented 3 years ago
I got the code you did.
Is there any usecase for having the same class instantiated more than once for the same id ?
Grzegorz Bujański staff commented 3 years ago
I don't think so. Most of the time this will cause bugs and so far I have not encountered the need to create more than one instance on the same element.
sody priority commented 3 years ago
Thats exactly is my point.Maybe you should change the code as to do getInstance only which in turn create new or return the current already instantantiated.
Dont get me wrong I already applied your "fix" in my code and it works.
Another thing wpuld be add a example in the docs to do what you suggested for new commers.
Sami
Grzegorz Bujański staff commented 3 years ago
We just plan to block the possibility of creating another instance of the class on the same element. It will work as you say - it will create a new instance of the class or return an existing one.
Grzegorz Bujański staff answered 3 years ago
I solved the problem that was visible in the snippet. It looks like you created a new instance of the modal class each time you closed the modal.
check this snippet: https://mdbootstrap.com/snippets/standard/grzegorz-bujanski/3282195 I corrected the loadModal1 method with it
sody priority commented 3 years ago
HI,Thank you, well test it. How do you explain that switching to hidden.bs.modal event doesn't create the probelm? And how about the solution i suggested ?
sody priority commented 3 years ago
Hi,
I've tested and its working. Thank you.
you didn't answer my last question.
Sami
Grzegorz Bujański staff commented 3 years ago
Which question exactly?
FREE CONSULTATION
Hire our experts to build a dedicated project. We'll analyze your business requirements, for free.
Answered
- ForumUser: Priority
- Premium support: Yes
- Technology: MDB Standard
- MDB Version: MDB5 3.9.0
- Device: desktop
- Browser: chrome
- OS: windows10
- Provided sample code: No
- Provided link: No
Grzegorz Bujański staff commented 3 years ago
Unfortunately, I am unable to reproduce this error. Please prepare a snippet in which this error will occur. I'll check what's going on.
sody priority commented 3 years ago
here is it:
https://mdbootstrap.com/snippets/standard/sody/3279067
I added a log to the screen.. simply hit open modal, cancel, open modal, cancel....
you *should * see after each "Cancel" added "hidden" to the log, in this example you'll see exactly that after 3 "cancel":
(1) hidden
(2) hidden
(3) hidden
(4) hidden
(5) hidden
(6) hidden
instead of:
(1) hidden
(2) hidden
(3) hidden
sody priority commented 3 years ago
I think I know the problem...
going over the code of pro/modal.js and bootstrap/mdb-prefix/modal.js i think the problem is in pro/modal.js the events bind using "on" instead of "one" as in bootstrap/mdb-prefix/modal.js - that should be changed too in all the function events..
_bindHiddenEvent() { EventHandler.on(this._element, EVENT_HIDDEN_BS_MODAL, () => {
should be turned to:
_bindHiddenEvent() {
same for all:
_bindShowEvent();
_bindShownEvent();
_bindHideEvent();
_bindHiddenEvent();
_bindHidePreventedEvent();