metismenujs icon indicating copy to clipboard operation
metismenujs copied to clipboard

Submenu is not closing when user clicks outside of its container in horizontal menus.

Open gurumark opened this issue 5 years ago • 14 comments

Describe the bug Submenu cannot be hidden when user clicks outside of its container

To Reproduce 1- Go to http://onokumus.com/metismenujs/mm-horizontal.html 2- Click any menu with submenu 3- Slick outside of submenu

Expected behavior It should close the submenu open

Screenshots If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information): Any browser

Smartphone (please complete the following information): Any device

Additional context No additional context

gurumark avatar Oct 09 '18 01:10 gurumark

Hi @gurumark I have fixed clickable horizontal menu, but not yet the other. Have you any idea?

onokumus avatar Oct 09 '18 10:10 onokumus

I don't think you need to fix the vertical one. For vertical menus, it is not expected a menu section to close when user clicks outside.

Is it possible publish a new release with the fix?

gurumark avatar Oct 09 '18 12:10 gurumark

I think you misunderstood me. I'm talking about the first menu (horizontal clickable, not horizontal hoverable) in http://onokumus.com/metismenujs/mm-horizontal.html page. The vertical menu is already working properly.

No need for new release. I changed just http://onokumus.com/metismenujs/assets/js/mm-horizontal.js file.

onokumus avatar Oct 09 '18 13:10 onokumus

"I have fixed clickable horizontal menu, but not yet the other. " Which one is the "other"? and what is not working there?

gurumark avatar Oct 09 '18 13:10 gurumark

Which one is the "other"?

  • Hoverable for Desktop

onokumus avatar Oct 09 '18 13:10 onokumus

What's not working there?

gurumark avatar Oct 09 '18 14:10 gurumark

Ohh I see... the second level menus are not opening up.

gurumark avatar Oct 09 '18 14:10 gurumark

How does the solution you have for the horizontal menu support "multiple menus" on the same page?

gurumark avatar Oct 10 '18 14:10 gurumark

Same, you can call MetisMenu as many times as you want.

document.addEventListener("DOMContentLoaded", function(event) {

  const mm1 = new MetisMenu("#menu1").on("shown.metisMenu", function(event) {
    window.addEventListener("click", function mmClick1(e) {
      if (!event.target.contains(e.target)) {
        mm1.hide(event.detail.shownElement);
        window.removeEventListener("click", mmClick1);
      }
    });
  });

  const mm2 = new MetisMenu("#menu2").on("shown.metisMenu", function(event) {
    window.addEventListener("click", function mmClick2(e) {
      if (!event.target.contains(e.target)) {
        mm2.hide(event.detail.shownElement);
        window.removeEventListener("click", mmClick2);
      }
    });
  });

});

onokumus avatar Oct 10 '18 14:10 onokumus

Yes, I see that but you're repeating the same code again and again. Don't you?

gurumark avatar Oct 10 '18 14:10 gurumark

What you wanna do? Can you give me some detail?

onokumus avatar Oct 10 '18 14:10 onokumus

Here is what I've done:

var box = document.querySelectorAll("#topmenu-right ul.w3-card-4"); var menu = document.querySelectorAll("#topmenu-right ul.metismenu li");

document.addEventListener("click", function(event) { // If user clicks inside the element, do nothing if (event.target.closest(".w3-top")) return; if (event.target.closest("ul.w3-card-4")) return;

// If user clicks outside the element, hide it! var i; for (i = 0; i < box.length; i++) { box[i].classList.remove("in"); } for (i = 0; i < menu.length; i++) { menu[i].classList.remove("active"); } }); Basically, I am removing the "active" and "in" classes whenever a user clicks outside of the menu bar.

gurumark avatar Oct 10 '18 14:10 gurumark

MetisMenu works event-based. If the event does not complete, MetisMenu will not function properly. Therefore if you remove css classes manually, MetisMenu will not function properly.

What can you do? You can create a instance from the MetisMenu class. With this instance, you can call functions (hide, show, dispose, update) in MetisMenu.

https://github.com/onokumus/metismenujs#events

See the examples on this pages; https://onokumus.com/metismenujs/mm-horizontal.html https://onokumus.com/metismenujs/mm-event.html https://onokumus.com/metismenujs/mm-event2.html https://onokumus.com/metismenujs/mm-github.html

onokumus avatar Oct 10 '18 18:10 onokumus

I agree. However, you want to simplify the initialization right? Since you already now the id, you can pass it to your code and do the processing there. Then users don't need to deal with event listeners and all. The only moving part in your code is the id, the others are variables or constant names.

gurumark avatar Oct 10 '18 21:10 gurumark