If you need just a very basic drop down that works in Casper there’s also this one…
This is the most rudimentary of drop downs, just copy-and-paste code into your Site’s Header and Footer Code Injections in the Admin area of your Ghost site, and add a dash and a space to a Primary Navigation Menu Item to make that item appear in a drop down menu below the Menu Item above it.
So this can be installed and configured on hosted sites or in other circumstances where you only have Admin access.
Credit goes to @ahmadajmi at Aspire Themes where I got the idea and the inspiration for …
Joan
November 9, 2022, 7:03pm
50
I can’t get it to work with Casper theme, could you help me?
I added all on Site footer of Ghost:
<script src='https://xxxxxxxx.com/assets/css/ghost-dropdwon.css'></script>
<script src='https://xxxxxxxx.com/assets/js/ghost-dropdown.js'></script>
$(document).ready(function () {
ghost_dropdown({
targetElement: "nav.ul li",
hasChildrenClasses: "menu-item-has-children",
hasChildrenIcon: "<svg width='19' height='10' viewBox='0 0 19 10' fill='none' xmlns='http://www.w3.org/2000/svg'><path d='M1.74805 1.52002L9.54883 9.00002L17.3496 1.52002' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/></svg>",
hasChildDetectText: "[has_child]",
submenuUlClasses: "ghost-submenu",
subitemDetectText: "[subitem]",
subitemLiClasses: "subitem",
multi_level: false,
mega_menu: false
});
});
And the result is…
@Joan you have an error in your CSS include:
That one needs style tags…
<style> ..etc... </style>
Joan
November 9, 2022, 8:04pm
52
The same @denvergeeks … Seems Ghost not detect the .JS script or it’s wrong, beacuse the menu shows the elements with [has_child] and [subitem].
The instructions of @themeix is wrong too i think…
Any idea on how to make this work with Headline?
Dropdown primary nav menu in Headline
Great, but it didn’t work on my phone! but it worked perfectly on desktop!
@saiunes What did not work?
Also, did you try this one…
This is the most rudimentary of drop downs, just copy-and-paste code into your Site’s Header and Footer Code Injections in the Admin area of your Ghost site, and add a dash and a space to a Primary Navigation Menu Item to make that item appear in a drop down menu below the Menu Item above it.
So this can be installed and configured on hosted sites or in other circumstances where you only have Admin access.
Credit goes to @ahmadajmi at Aspire Themes where I got the idea and the inspiration for …
1 Like
Hi, I am trying to use the script in an Edition theme but the image looks like below. Which part of the javascript takes out the [has_child] and [subitem] bits out of the menu items?
is jQuery getting loaded, @Tada_Hozumi ? What shows up in the console logs? (F12 to open developer tools, then click the ‘console’ tab.)
and my script that i copy/pasted looks like this:
I’d guess that jquery isn’t loaded by this theme. Try adding a line to load it before this script.
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="https://code.jquery.com/jquery-3.6.3.min.js"></script>
If that doesn’t work, paste it instead into your Site Header Code Injection…
Please do report back here your results…
denvergeeks:
<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>
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
OK @Joan I’ve got a new rendition of the script for the footer injection. I’ve also edited and commented a little more in the CSS.
For the script I just followed the example of the new overflow click-down menu in Casper. (The code you linked to at Added navbar options (#906) · TryGhost/Casper@cf30ada · GitHub )
Here’s what I’ve got now that’s working correctly. (This code might have extra cruft that can be removed. Hopefully someone better at JS can tell us.)
The CSS for the Site Header Code …
ah thank you, gonna try that out