codrops / MultiLevelMenu

A simple menu with multiple levels and an optional breadcrumb navigation and back button.
232 stars 83 forks source link

change of starting index doesn't allow usage of back / breadcrumbs control #3

Open paulhaem opened 8 years ago

paulhaem commented 8 years ago

Hello, first of all I want to thank you for this awesome blueprint. :-) I tried to make a non-ajax navigation out of it and managed to open the corresponding submenu via this.current when a subpage is loaded. But as I changed the index the back and breadcrumbs mistake it for the starting index / main menu and the controls do not behave accordingly. Is there any possibility to avoid this or to set a initial submenu when the page is loaded?

schonhose commented 8 years ago

Could you share your work with the non-ajax navigation? I am facing the same problem.

paulhaem commented 8 years ago

It's pretty specific. I managed to include the navigation as part of a CMS (Contao). The navigation will be auto generated. In the meantime I tried to open the corresponding submenu after initialization with the integrated function _openSubMenu. It worked on the first glance, but after you open a page on the 2nd level, it doesnt know anything about the 1st level and jumps to the root level after clicking the back-Button.

submenu_1.2 -> main instead of submenu_1.2 -> submenu_1 -> main

cirmic commented 8 years ago

I have a non-ajax navigation issue too!

I have a menu like this:

When i click to one of the submenu, the page will be refreshed and the menu return to the main state. I'd like that when i click to submenu 2.2 and after the page reload, the menu keep the state and show submenu 2.2 .

airomero commented 8 years ago

Any luck with this anyone?

paulhaem commented 8 years ago

Not yet, I changed to "mmenu" for better performance and usability. Too bad theres no help from the developer here. :/

DarioCorno commented 7 years ago

I solved (partially) this problem with this function:

   MLMenu.prototype.autoSelectMenu = function() {
       var self = this;

        var curLoc = window.location.href;
        var links = document.getElementsByClassName('menu__link');
        var item = null;
        var curItem = null;
        for(var i = 0, len = links.length; i < len; i++) {
            item = links[i];
            if( curLoc.substring(0, item.href.length) === item.href) {
                curItem = item;
            }
        }

        //we are in the root or in a unknown url
        if( curItem == null)
            return false;

        classie.add(curItem, 'menu__link--current');

        //we found the current active link
        //lets find in which menu is it
        var curMenuEl = findAncestor(curItem,'menu__level');
        var menuIdx = this.menus.indexOf( curMenuEl );
        //the link is in the root menu
        if(menuIdx == 0)
            return false;

        var linkDataMenu = curMenuEl.getAttribute('data-menu');
        //find the original link that lead here
        var link = document.querySelectorAll("[data-submenu='" + linkDataMenu + "']");
        var menuName = link[0].innerText;

        this.current = menuIdx;
        this.isAnimating = false;

        if ( (curMenuEl != null) && (curMenuEl.getAttribute('data-menu') == 'main' ) )
            return false;
        self._activateSubMenu(curMenuEl, menuIdx , menuName);

    };

   //activates a sub menu instantly without animation
    MLMenu.prototype._activateSubMenu = function(subMenuEl, clickPosition, subMenuName) {
        this.isAnimating = false;

        //TODO: insert the real parent, this is now 0, assuming a maximum depth of 2 menus (main and sub)
        // save "parent" menu index for back navigation
        this.menusArr[this.menus.indexOf(subMenuEl)].backIdx = 0; /* this.current */;
        // save "parent" menu´s name
        this.menusArr[this.menus.indexOf(subMenuEl)].name = subMenuName;
        // find the current menu and disable it
        var curMenu = document.getElementsByClassName('menu__level--current');
        for(var i =0; i < curMenu.length; i++) {
            classie.remove( curMenu[i],'menu__level--current');
        }
        //directly show the correct menu without animations
        classie.add(subMenuEl, 'menu__level--current');

        // show the back button
        if( this.options.backCtrl ) {
            classie.remove(this.backCtrl, 'menu__back--hidden');
        }

        // add breadcrumb
        this._addBreadcrumb( this.menus.indexOf(subMenuEl) );

    };

and calling this.autoSelectMenu(); just before this._initEvents();

lakesta commented 7 years ago

PR Added for this @ https://github.com/codrops/MultiLevelMenu/pull/6

bohdansmaha commented 7 years ago

@DarioCorno I was able to load current menu, but the breadcrumbs and back arrow don't work. Were you able to have the whole menu function as before with the initial index on the current page?

@lakesta can you assist with the example of non-ajax navigation

thokaro commented 7 years ago

DarioCorno, i get the following error ...

Uncaught ReferenceError: findAncestor is not defined

Could you post the function please?

aklimaruhina commented 7 years ago

how can i get back to main link. can anyone help on it?

vladojovanovski commented 7 years ago

Hope this approach to the issue will help someone. Add following to main.js

MLMenu.prototype._activateSubMenu = function(subMenuEl) { this.isAnimating = false; for (var i = 0, lenI = this.menusArr.length; i < lenI; i++) if (this.menusArr[i].menuEl == subMenuEl) break; if ("backIdx" in this.menusArr[i]) if (this.menusArr[i].backIdx) this._activateSubMenu(this.menusArr[this.menusArr[i].backIdx].menuEl); classie.remove(this.el.querySelector('.menulevel--current'), 'menulevel--current'); classie.add(subMenuEl, 'menu__level--current'); this.current_menu = i; if (this.options.backCtrl) classie.remove(this.backCtrl, 'menu__back--hidden'); this._addBreadcrumb(this.menus.indexOf(subMenuEl)); };

After initializing the menu call the desired sub-menu by id. Example: mlmenu._activateSubMenu(document.getElementById("submenu-4-1"));