Add Dropdowns to Main Menu Through the Site Admin (Copy & Paste into Site Header/Footer Injections)

To add dropdowns to your main menu through your site admin area.

These instructions are just a simplification of the @themeix drop down mentioned here, but for more noobish front-enders (as this is without modifying templates or other theme files)…

Paste the following CSS in your Site Header Injection:

<style>

/* For Dropdown Menus */    
li.menu-item-has-children {
    position: relative;
    padding-right: 25px!important;
    display: inline;
}
    
li.menu-item-has-children:hover ul.ghost-submenu {
    visibility: visible!important;
    opacity: 1!important;
    top: 50px!important;
}

.menu-item-has-children svg {
    position: absolute;
    right: 0px;
    top: 60%;
    transform: translate(-0%, -50%) scale(1.1);
}

ul.ghost-submenu li {
    list-style: none;
    white-space: nowrap;
}

ul.ghost-submenu {
    border-radius: 5px;
    position: absolute;
    visibility: hidden;
    z-index: 1;
    opacity: 0;
    top: 30px;
    transition: 0.3s;
    box-shadow: 0 1px 5px 0 rgb(0 0 0 / 14%);
    max-width: unset !important;
    
    /* Edit below to adjust Dropdown Menu positioning and color */
    left: 0;
    margin-top: -15px;
    padding: 5px 20px 10px 10px;
    background: #fff;
    color: #000;
}

</style>

And paste the following Javascript into your Site Footer Injection:

<script>
// For Dropdown Menu
(function($) {
    "use strict";
    function ghost_dropdown(options) {
       let defultOptions = {
            targetElement: "ul li",
            hasChildrenClasses: "menu-item-has-children",
            hasChildrenIcon: "<svg xmlns='http://www.w3.org/2000/svg' width='11' height='7' fill='currentColor' class='bi bi-caret-down' viewBox='0 0 11 7'><path d='M5.4999 6.20003L0.649902 1.35003L1.3499 0.650024L5.4999 4.80002L9.6499 0.650024L10.3499 1.35003L5.4999 6.20003Z'/></svg>",
            hasChildDetectText: "[has_child]",
            submenuUlClasses: "ghost-submenu",
            subitemDetectText: "[subitem]",
            subitemLiClasses: "subitem"
        }
        options = {
            ...defultOptions,
            ...options
        }
        console.log(options);
        // Target Element
        let targetElement = options.targetElement;
        //Default value 
        let hasChildrenClasses = options.hasChildrenClasses;
        let hasChildrenIcon = options.hasChildrenIcon;
        let hasChildDetectText = options.hasChildDetectText;
        let submenuUlClasses = options.submenuUlClasses;
        let subitemDetectText = options.subitemDetectText;
        let subitemLiClasses = options.subitemLiClasses;
        // Declare neccesary variable
        let parentEl = $(targetElement);
        let childEL = $(targetElement);
        let parentLen = 0;
        let domArrayElement = [];
        let indexPush = [];
        let elIndex = 0;
        let parentIndex = [];
        $(`${targetElement}`).parent().addClass('ghost-dropdown-menu');
        // Find Dropdown parent element
        parentEl.each(function(index, element) {
            if ($(this).text().indexOf(hasChildDetectText) >= 0) {
                parentIndex.push(index); // Make dropdown parent array index
                parentLen++;
                $(this).push(element);
                $(this).addClass(hasChildrenClasses); // Add class in dropdown element
                $(this).append(`<ul class='${submenuUlClasses}'></ul>`); // Append submenu element
                $(targetElement).css("opacity", "1");
            }
        });
        $(`.${hasChildrenClasses}`).append(hasChildrenIcon);
        // Using loop to reach dropdown parent element
        for (let i = 0; i < parentLen; i++) {
            elIndex = 0 // Initial element value
            // Find subitem element
            childEL.each(function(index, element) {
                let subitem = $(this).text().includes(subitemDetectText); // Find subitem element
                if (subitem) {
                    if (elIndex >= parentIndex[i + 1]) { // Each loop will be break
                        return false; //Stoped each loop 
                    }
                    if (elIndex <= parentIndex[i + 1] || elIndex >= parentIndex[parentIndex.length - 1]) {
                        if (!indexPush.includes(index)) { //Check if not index already insert 
                            $(this).addClass(subitemLiClasses); // Add class in subitem element
                            let st = $(this).children().text(); // Find subitem inner text
                            $(this).children().text(st.replaceAll(subitemDetectText, "")); // Replace subitem inner text
                            domArrayElement.push(element); // Incert subitem element in dom array
                            indexPush.push(index); // incert subitem index in indexPush array
                        }
                    }
                }
                elIndex++; // increase element index value
            });
            $(`.${hasChildrenClasses} ul.${submenuUlClasses}:eq(${i})`).append(domArrayElement); // Append related subitem dom element into submenu 
            // console.log(domArrayElement);
            domArrayElement = []; // Make dom array element empty. 
        }
        const hasChildEl = $(`.${hasChildrenClasses}`);
        hasChildEl.each(function() {
            if ($(this).find("> a:first").text().includes(hasChildDetectText)) {
                console.log($(this).find("> a").text());
                let hasChildText = $(this).find("> a:first").text(); // Find has child inner text
                $(this).find("> a:first").text(hasChildText.replaceAll(hasChildDetectText, ""));
            }
        });
    }
    $(document).ready(function() {
        ghost_dropdown();
    });
}(jQuery));
</script>

Then, just add the menu items in your ghost admin dashboard like so…


The above code should work as-is in Casper for single-level dropdown menus, but you might need to adapt the CSS to fit your and/or tweak the selectors for other themes.

**If you need multi-level drop downs, or full mega-menus that you can also manage strictly through the admin interface, @themeix Newsfeed Theme has that as well.

8 Likes

With Casper 5.X the CSS
Captura de pantalla 2022-06-02 a las 20.12.15
not work correctly…

@Joan thanks for testing that. I’ve corrected the Header Injection code snippet above so it works correctly in the current Casper.

1 Like

Great post… it will help others. Thanks mate for your sharing.

Now yes! Thanks you so much! It’s would possible to add a divider between two links in submenu?

@Joan – so, to add lines below each submenu item (except the last one, which would look strange) like this…

You need to modify the CSS like so…

ul.ghost-submenu li {
    list-style: none;
    white-space: nowrap;
    border-bottom: 1px solid #ddd;
}
    
ul.ghost-submenu li:last-child {
    border: none;
}

So you are adding the following into the CSS…

1 Like

Thanks for all mate!!! :slight_smile:

Thank you for sharing the code to creating this dropdown feature!

I tried it out in the dawn theme and it works, but the pages in the dropdown menu are not aligned properly. Do you have any solution to fix this?

Thanks in advance!

Screen Shot 2022-08-12 at 11.08.45 AM

@Maaike_Schilperoort – if what you want is for all of the 3 items inside the drop-down to be aligned to the left, you can add this to the end of the CSS snippet above…

ul.ghost-submenu li {
    margin-left: 0 !important;
}
2 Likes

That works, thank you!!

2 Likes

Is there a way to add multiple dropdowns to the main menu? I am aware of the secondary navigation options that you can change in Settings and am using the Liebling theme, so I have one dropdown with those links but would prefer a dropdown for every top-level menu item.

@adam have you tried adding multiple drop downs using the code provided here?

Here is a post with a YouTube Video showing it working for multiple dropdowns:

Where do you add the [has_child]?

In the Admin Dashboard → Settings → Navigation… so for example:

… generates this drop-down menu under my Engage Primary link …

1 Like

I added the [has-child] and [subitem] to the Nav list of pages, but all that does is add those tags to the navigation. For example, Our Story is the parent and Our Team is supposed to be its child, but instead I get this:

Is there somewhere else I need to add those tags?

@PerseidsGirl are you using Casper?

What is the URL of your site?

Is the menu item with [subitem] directly underneath the menu item with [has_child] in your Primary Navigation settings? It needs to be.

Also, [has-child] will not work… it needs to be an underscore, not a dash in between has and child…

Please post your header and footer injections…

Thank you for your assistance @denvergeeks
This is my site so far: https://moodfuel-news.ghost.io/
It’s the Daily News theme from @GBJsolution
I’ll correct the dashes to underscores.

Header

/* For Dropdown Menus */ li.menu-item-has-children { position: relative; padding-right: 25px!important; display: inline; } li.menu-item-has-children:hover ul.ghost-submenu { visibility: visible!important; opacity: 1!important; top: 50px!important; } .menu-item-has-children svg { position: absolute; right: 0px; top: 60%; transform: translate(-0%, -50%) scale(1.1); } ul.ghost-submenu li { list-style: none; white-space: nowrap; } ul.ghost-submenu { border-radius: 5px; position: absolute; visibility: hidden; z-index: 1; opacity: 0; top: 30px; transition: 0.3s; box-shadow: 0 1px 5px 0 rgb(0 0 0 / 14%); max-width: unset !important; /* Edit below to adjust Dropdown Menu positioning and color */ left: 0; margin-top: -15px; padding: 5px 20px 10px 10px; background: #fff; color: #000; }

Footer:

@PerseidsGirl as mentioned above…

Since you are using the Daily News theme you will need to adapt the CSS and/or selectors to make it look and behave correctly on your site :nerd_face:

Looking at your site right now, I can see that the dropdown is now appearing since (I assume) you moved the menu item with [subitem] to directly underneath the menu item with [has_child] and correct the dashes to underscores.

Now, to make the link appear, add something in your CSS like…

ul.ghost-submenu {
    background: #000;
}

or…

ul.ghost-submenu li a {
    color: #000;
} 

… and adjust your padding to something like this…

ul.ghost-submenu {
    padding: 15px 20px 10px 20px;
}
    
1 Like

This is great, but it only lets me select the top item in the dropdown list? site: thedansmock.com

@thedansmock - the dropdown on your site is not using the code presented in this Topic. Rather, it appears to be generated by a tooltip. Also, the theme you are using appears to be Liebling, not Casper.