Simple Mega Menus with Beaver Builder and Beaver Themer

I’ve played with a million mega menu plugins over the years – they were all too complex or too simple or was just not user friendly. So I built my own.

I have this saved in my template WordPress install, so that I can easily create a mega menu whenever I want. I’m not going to lie, you can’t be a complete rookie to make mega menus with this code. You need to know about how to create Beaver Themer parts, and set an ID for your rows. If that makes sense to you, then please, right this way….

Watch the video, and then steal the code 🙂

How & Why it Works

  1. Add the ID my-mega-menu to your Beaver Builder menu. – The code will then search this menu for mega menus.
  2. Create a Beaver Themer part, make it visible on the entire site. – This is where we will create the mega menu rows.
  3. Create Rows inside the Themer part – each row is an individual mega menu.
    • For each menu item, create a Row and give the row a special ID. this is where the code does its magic
      • The code takes the menu item name, and looks for a lowercase version, and replaces all non alphanumeric (? ! $ % etc) with a dash , starting with “mega-
      • Contact Us menu item would have an associated mega menu ID of mega-contact-us
      • About maps to mega-maps
      • Services? -> mega-services-
      • Isn’t this it? -> mega-isn-t-this-it
      • weird! things?!# here -> mega-weird-things-here (note the multiple non-alphanumeric in a row characters turn into 1 dash)
      • Stuck? Use the helper function megaDebug() in the console to see all the mega menu row ID’s that you can use.
      • The code does the rest.
  4. On larger screens, the corresponding mega menu will show up under each menu item.
  5. On mobile screens, all the mega menus will be shown, stacked on top of each other when the user clicks the menu/hamburger menu.

The JS:

To add JS sitewide:

  1. Open any page with Beaver Builder
  2. Click the title bar in the upper left corner to open the Tools menu, then click Global settings.
  3. On the JavaScript tab, enter this JavaScript code.
  4. Click Save.
// mega menu js

var menuElement = "#my-mega-menu .menu-item";
var mobileToggle = '.fl-menu-mobile-toggle';

jQuery(document).ready(function(){
  
    // exit if bb is running
    if(jQuery('body').hasClass('fl-builder-edit'))
        return true; 

    //add the helper parent class to the mega menu for mobile
    jQuery('[id^="mega-"]').first().parent().addClass('mega-mobile-container')


    //set top location of 
    jQuery(window).on('resize', function () {
        if(isMobile())// set init value
        {
            //set top value of container
            topValue = jQuery(mobileToggle).offset().top + jQuery(mobileToggle).outerHeight(); 
            jQuery('.mega-mobile-container').css('top',topValue + 'px');
            
        }
        else
        {
            jQuery('.mega-mobile-container').css('top','');
            jQuery('.show-mega-mobile').removeClass('show-mega-mobile');
            topValue = 0;
        }
        
        jQuery(menuElement).each(function(){

            var menuItem = jQuery(this);
            var megaItem = jQuery("#"+"mega-"+menuItem.text().replace(/[\W_]+/g,"-").toLowerCase());
            
            if(megaItem.length) // if its  mega anything
            {
                //set up click listeners for menu items 
                menuItem.click(function(event) {
                    
                    mm = jQuery("#"+"mega-"+jQuery(this).text().replace(/[\W_]+/g,"-").toLowerCase());
                    // if it has a mega menu
                    if(mm.length && !isMobile())
                    {
                        event.preventDefault();
                        event.stopPropagation();
                        if(!mm.hasClass('show-mega'))
                        {
                            jQuery('.show-mega').removeClass('show-mega');
                            mm.addClass('show-mega');
                            
                        }
                        else
                            mm.removeClass('show-mega');
                    }
                    
                });

                if(isMobile())
                {
                    megaItem.css('top',  topValue + 'px');
                    topValue += megaItem.height();
                }
                else
                {
                    jQuery('body').removeClass('show-mega-mobile');
                    topValue = menuItem.offset().top + menuItem.outerHeight();
                    megaItem.css('top',  topValue + 'px');
                }
            }
               
        });
    }).resize();
    
    jQuery(mobileToggle).click(function(event){
        event.preventDefault(); // stop the inbuilt stuff from stuffin
        event.stopPropagation();
        jQuery('body').toggleClass('show-mega-mobile');
    });
    
    
    //close mega menu stuff
    
    // escape click    
    jQuery(document).on('keyup', function(e) {
      if (e.key == "Escape")
      {
        jQuery('.show-mega').removeClass('show-mega');
        jQuery('body').removeClass('show-mega-mobile');
      }
    });
    
    //click outside of mega menu
    jQuery(document).on('click', function (e) {
        if (jQuery(e.target).closest('[id^="mega-"], .mega-mobile-container').length === 0) {
            if(jQuery('.show-mega, .show-mega-mobile').length){
                jQuery('[id^="mega-"]').removeClass('show-mega');
                jQuery('body').removeClass('show-mega-mobile');
            }
        }
    });

});

function isMobile(){
    return (FLBuilderLayoutConfig.breakpoints.small > jQuery(window).width());
}

function megaDebug(){
    jQuery(menuElement).each(function(){
        console.log("mega-"+jQuery(this).text().replace(/[\W_]+/g,"-").toLowerCase());
    });
}

EDIT 1: 2 JUN 2021

Changed from on hover to on click. Its just better 🙂

EDIT 2: 3 JUN 2021

  • Fixed the text parser to replace all non alphanumeric with a dash
  • Added megaDebug() function. Run it in your console to see what your mega menu row ID’s should be.

The CSS:

To add CSS sitewide:

  1. Open any page with Beaver Builder
  2. Click the title bar in the upper left corner to open the Tools menu, then click Global settings.
  3. On the CSS tab, enter this CSS code.
  4. Click Save.
body:not(.fl-builder-edit) [id^="mega-"] {
    -webkit-transition: all 300ms ease-in-out;
    -moz-transition: all 300ms ease-in-out;
    -ms-transition: all 300ms ease-in-out;
    -o-transition: all 300ms ease-in-out;
    transition: all 300ms ease-in-out;
    z-index: 100;
}
.show-mega{
    visibility: visible !important;
    opacity: 1 !important;
    z-index:101 !important;
}
/* mobile stuffs */
body.show-mega-mobile [id^="mega-"]{
    visibility: visible !important;
    opacity: 1 !important;
}


/* small screens mega settings*/
@media (max-width: 767px){
    
    .mega-mobile-container{
        visibility: hidden;
        opacity: 0;
        position: fixed;
        top:150px;
        left: 0;
        bottom: 0;
        overflow-y: scroll;
        width: 100%;
        z-index: 100;
    }
    
    .show-mega-mobile .mega-mobile-container{
        visibility: visible !important;
        opacity: 1 !important;
    }
    
}
/* bigger screens mega settings*/
@media (min-width: 768px){
    
    body:not(.fl-builder-edit) [id^="mega-"] {
        visibility: hidden;
        opacity: 0;
        position: fixed;
        top:150px;
        left: 0;
        width: 100%;
    }    
    
    
}

Comments:

9 Comments

  1. Ben on June 1, 2021 at 7:21 pm

    Hey there! I love this! So much simpler than some of those menus like Quad Menu.

    Any chance to consider revealing the dropdown on a click?

    https://css-tricks.com/in-praise-of-the-unambiguous-click-menu/

    • Tom on June 1, 2021 at 8:23 pm

      Thanks Ben!

      When you’re right, you’re right. I’ll update the code in the next few days for the unambiguous click.

  2. Craig on June 3, 2021 at 5:03 am

    Hi Tom.

    This is an excellent solution, thank you.

    I have a slight issue in that some of my menu items contain a question mark, which stops the mega menu from working.

    Is there any chance you could update the JS to allow for this please.

  3. Craig on June 3, 2021 at 9:51 am

    Also noticed another issue, I’m getting a gap above each subsequent mega menu…

    Here is a short clip of the issue – https://cln.sh/uFpkhDG1xdAURei758qI

    Unfortunately the site is only on local at the moment, but if you need any further info I can provide it.

  4. Tom on June 3, 2021 at 11:00 am

    Thanks Craig!

    I’ve updated the code to replace all non alphanumeric characters, so your ?’s and !’s should now be replaced with a single “-”

    Just FYI, the code is also updated to on click now, its much better UX than “on hover” 🙂

    I added the helper function megaDebug() so you can see what your mega menu row ID’s should be after being parsed. Just type megaDebug() into the console, and it will tell you the mega names.

    As for the other issue – I can’t really say without seeing it live. Its a good looking site though! Push it onto a server and send me a link, we’ll get it working for you 🙂

    • Craig on June 3, 2021 at 3:14 pm

      Wow! That’s fantastic Tom. Thank you.

      I have emailed you separately with a link and another query.

      Best regards,
      Craig

  5. Heather Steele on June 3, 2021 at 7:08 pm

    This is fantastic! I have been wanting to do just this on a few sites but didn’t have the time or brains to work it out — super excited!

    • Tom on June 8, 2021 at 9:56 am

      Awesome! Please share some links to some completed sites!

  6. Craig on June 9, 2021 at 4:16 am

    Hi Tom, sorry to pester you. Did you happen get a chance to look into my issue at all? I sent an email via the contact form with URL. Let me know if you need anything further to help troubleshoot.

Leave a Comment





Level up your Beaver Builder skills

Over 2,000 Beaver Builders can't be wrong!

We've got a million ideas that we've implemented on over 100+ BB enabled websites.

Pop in your email below, and we'll let you know when a new post or plugin is available :)

Newsletter

  • This field is for validation purposes and should be left unchanged.

Spam sucks.