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

i’m sorry to be such a neophytye … is it possible for you to share how that’s done?

Paste this into your Site Footer Code injection:

<script src=""></script>

If that doesn’t work, paste it instead into your Site Header Code Injection…

Please do report back here your results…

Hi! It loads now, but I get a moment of it showing the links as X [has_child] X [subitem] before it shows the dropdown … is there a fix to this loading issue?

The problem is that the code runs late in the page load. Including it in the .hbs file (and avoiding jQuery) helps a LOT but then it’s no longer a code injection solution.

I see. Actually, I posted it to the main site from my test and it stopped working at all… hmmph.

I’m curious if you have an opinion

Please nvm if that is too much fuss.

@Tada_Hozumi You could try this one which loads smoothly and without that flash

ah thank you, gonna try that out

tysm for your generous help @denvergeeks.

I was wondering, for the selectors in Edition:

I am assuming this is wrong but I can’t seem to find the right two selectors.

Here is the source code:

@Tada_Hozumi you are most welcome!

If you are asking about the other dropdown at Hover-Down Submenus for Casper Here then let’s move this discussion over to that thread.

In answer to your question, though – that one at Hover-Down Submenus for Casper Here works correctly in the Edition Theme as-is :cowboy_hat_face:

If you need more help with that one, please post over on that thread.

1 Like

@denvergeeks thank you so much for this script. it really helped me a lot.
I would have one question though. Is there any chance the drop down menu can be responsive to some degree based an on the length of the string.

As you can see on the screenshot, one menu item " Bank Payments" breaks.
Could you please be so kind and give me a hint where in the script I can make changes to expand the size of the drop down menu based on the string length?

Thank you in advance.

OK I’ve got a working version now for the Liebling Theme… (You can put as many of these dropdowns as you want in your site menu.)

Site Header Injection:


/* START - For Dropdown Menus in Liebling */ {
    position: relative;
    padding-right: 20px !important;
    align-items: center;
    display: inline-flex;
} ul.ghost-submenu {
    visibility: visible !important;
    opacity: 1 !important;
    display: flex !important;
    flex-direction: column !important;
    align-items: flex-start !important;

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

ul.ghost-submenu li {
    list-style: none;
    white-space: nowrap;
    margin-bottom: 0;
    margin-right: 0;
    width: 150px;
ul.ghost-submenu li a {
	width: 100%;
    padding: 8px 10px;
    display: block;

    color: #fff;
    font-size: 1rem;
    transition: background-color .1s linear;
    border-radius: 4px;
ul.ghost-submenu li a:hover {
    background-color: rgba(0,0,0,.1);
ul.ghost-submenu {
    display: block !important;
    border-radius: 5px;
    position: fixed;
    visibility: hidden;
    z-index: 3;
    opacity: 0;
    top: 30px;
    transition: 0.3s;
    box-shadow: 0 1px 5px 0 rgb(0 0 0 / 14%);
    max-width: unset !important;
    padding: 5px 20px 10px 10px !important;
    background-color: #333;
    line-height: 1.4;
    outline: 0;
    transition-property: transform,visibility,opacity;
    white-space: normal;
/* END - For Dropdown Menus in Liebling */

Site Footer Injection…

<script src=""></script>

// For Dropdown Menu
(function($) {
    "use strict";
    function ghost_dropdown(options) {
       let defultOptions = {
            targetElement: "ul li",
            hasChildrenClasses: "menu-item-has-children",
            hasChildrenIcon: "<svg xmlns='' 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 = {
        // 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 = [];
        // Find Dropdown parent element
        parentEl.each(function(index, element) {
            if ($(this).text().indexOf(hasChildDetectText) >= 0) {
                parentIndex.push(index); // Make dropdown parent array index
                $(this).addClass(hasChildrenClasses); // Add class in dropdown element
                $(this).append(`<ul class='${submenuUlClasses}'></ul>`); // Append submenu element
                $(targetElement).css("opacity", "1");
        // 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() {
1 Like

@adam There is now a version of this that works with the Liebling Theme…

Did someone managed to apply it correctly when in mobile view, in the Penang theme?

I got it working successufully with few tweaks. But, when I switch to mobile view, the elements are not adjusted correctly.

An example of a perfectly working solution is the one implemented in the Learn. theme.