Ask your WordPress questions! Pay money and get answers fast! Comodo Trusted Site Seal
Official PayPal Seal

Accordion submenu WordPress

  • SOLVED

Hi there,

I'm using the Karma theme on my website. I use a template where there is a submenu on the side as you can see here: removed

I want to convert the submenu to an accordion, which acts on click and not on hover.
There is no real styling needed, only a '+' next to the parent page titles. When the user clicks on it, the content has to fade in instead of sliding and the + has to change into a - and vice versa.

Also, when a subpage is active, that parent needs to be opened when the page is loaded. So in our example when you click on 'Training > Basic training' and that page loads, all the parents should be collapsed except the Training one. That should be opened and have a red background and white font color as styling so the visitor knows that it's active.

I've tried to implement [[LINK href="http://www.designchemical.com/lab/jquery-vertical-accordion-menu-plugin/getting-started/"]]this[[/LINK]] accordion, but that one doesn't work in Safari and I don't know how to have only the active subpage opened.

Who can help me out?

Answers (3)

2011-09-19

Abdessamad Idrissi answers:

hey priktop,
what do you mean by : ..the content has to fade in instead of sliding..
since all the menus will be closed by default, clicking in on of them will slide the menus down to make room for sub-menus to show.


priktop comments:

Thank you for your reply.

I mean that when the submenu gets closed, the animation should be that the submenu fades oud instead of slides up. I hope this clears things up a bit.


priktop comments:

It's actually not a big of a deal if it slides, so don't let the fading thing hold you back :)


Abdessamad Idrissi comments:

ok, I created this for you

<script type="text/javascript">
$(document).ready(function() {
// hide all sub menu
$("#sub_nav ul li ul.sub-menu").hide();

// listen to clicks from parent menu only
$("#sub_nav ul li a").click(function() {
// hide all sub menu
$("#sub_nav ul li ul.sub-menu").hide();

// show the clicked submenu
$(this).next("ul.sub-menu").fadeIn("slow");

// if there's no next menu, then open that link
if ( $(this).next("ul.sub-menu").length > 0){
return false;
}
});
});
</script>


check if it works!


Abdessamad Idrissi comments:

here's the edited full code that will work without anyplugin!
just insert it somewhere in your theme, in the "footer.php" for example:

<script type="text/javascript">
$(document).ready(function() {
// hide all sub menu
$("#sub_nav ul li ul.sub-menu").hide();

// add "+" to all parent menu
$("#sub_nav ul li a span").before("<span>+</span> ");

// listen to clicks from parent menu only
$("#sub_nav ul li a").click(function() {
// hide all sub menu
$("#sub_nav ul li ul.sub-menu").hide();

// unhilite current menu
$("#sub_nav ul li").removeClass("current_page_item");

// close opened_menu - to +
$("#sub_nav ul li a span.opened_menu").html("+");
$("#sub_nav ul li a span.opened_menu").removeClass("opened_menu");

// show the clicked submenu
$(this).next("ul.sub-menu").fadeIn("slow");

// highlite current menu
$(this).parent("li").addClass("current_page_item");

// change + to -
$(this).children("span:first").html("-");
$(this).children("span:first").addClass("opened_menu");

// if there's no next menu, then open that link
if ( $(this).next("ul.sub-menu").length > 0){
return false;
}
});
});
</script>

hope it works :)


Abdessamad Idrissi comments:

If you don't want to use

var $j = jQuery.noConflict();
$j(document).ready(function() {
...

change all occurences of the "$j" symbol to "jQuery"
so instead of
$j(document).ready(function() {
// hide all sub menu
$j("#sub_nav ul li ul.sub-menu").hide();
...


you can use

jQuery(document).ready(function() {
// hide all sub menu
jQuery("#sub_nav ul li ul.sub-menu").hide();
...


priktop comments:

Thank you, but there are a couple of things that don't work well:

- All pages have a + sign, and not only the ones that can be opened.
- When I click on a childpage, the parent closes right before it goes to that page. That doesn't look nice.
- The + doesn't change into a - when opened.
- The child titles also havbe a + in front of them, which shouldn't be.
- The parent of a page isn't highlighted when active.

It's implemented now, so you can see how it functions.


Abdessamad Idrissi comments:

Ok.. I'll fix my previous code to meet the new requirement :)


Abdessamad Idrissi comments:

here's the final code :)

<script type="text/javascript">
jQuery(document).ready(function() {
// hide all sub menu
jQuery("#sub_nav ul li ul.sub-menu").hide();

// add "+" only to all parent menu
jQuery("#sub_nav ul li").has('ul').find("a span").not(jQuery("#sub_nav > ul li ul li a span")).before("<span>+</span> ");

// add "-" to current opened menu
jQuery("#sub_nav > ul li.current_page_item a span:first").html("-");
jQuery("#sub_nav > ul li.current_page_item a span:first").addClass("opened_menu");

// show current opened menu children
jQuery("#sub_nav > ul li.current_page_item ul.sub-menu").show();

// listen to clicks from parent menu only
jQuery("#sub_nav ul li a").click(function() {

// if subpage is clicked, then open that link without doing anything
if ( jQuery(this).next("ul.sub-menu").length == 0){
return;
}

// hide all sub menu
jQuery("#sub_nav ul li ul.sub-menu").hide();

// un-hilite current menu
jQuery("#sub_nav ul li").removeClass("current_page_item");

// close opened_menu - to +
jQuery("#sub_nav ul li a span.opened_menu").html("+");
jQuery("#sub_nav ul li a span.opened_menu").removeClass("opened_menu");

// show the clicked submenu
jQuery(this).next("ul.sub-menu").fadeIn("slow");

// highlite current menu
jQuery(this).parent("li").addClass("current_page_item");

// change + to -
jQuery(this).children("span:first").html("-");
jQuery(this).children("span:first").addClass("opened_menu");

// if there's no next menu, then open that link
if ( jQuery(this).next("ul.sub-menu").length > 0){
return false;
}
});
});
</script>


priktop comments:

Looking good! :) Almost there.

What I still want to see is that when you go to a subpage like [[LINK href="http://bit.ly/owSwRM"]]http://bit.ly/owSwRM[[/LINK]], the FAQ subpage should be opened, and must contain a class called 'current_page_item' to 'highlight' it.

There's also a little bug. When you go to pages that don't contain child pages, the page title disappears as you can see here: http://bit.ly/nsxmDU

Thanks.


priktop comments:

Oh wait, it doesn't work on Safari :(
When I click on a subpage that should open, it goes directly to that link. It's like Safari doesn't support jQuery?


Abdessamad Idrissi comments:

ok.. i'll fix that :)
one thing more; which code/plugin generates the menu? in other words - how the menus are generated? because the way they are generated is not the best one. Normally it should give distinctive class names for parent and child menus: now it gives the class "sub-menu" to both.


Abdessamad Idrissi comments:


<script type="text/javascript">
jQuery(document).ready(function() {
// hide all sub menu
jQuery("#sub_nav ul li ul.sub-menu").hide();

// add "+" only to all parent menu
jQuery("#sub_nav ul li").has('ul').find("a span").not(jQuery("#sub_nav > ul li ul li a span")).before("<span>+</span> ");

// add "-" to current opened menu
jQuery("#sub_nav > ul li.current_page_item").has('ul').find("a span:first").html("-");
jQuery("#sub_nav > ul li.current_page_item").has('ul').find("a span:first").addClass("opened_menu");

// show current opened menu children
jQuery("#sub_nav > ul li.current_page_item ul.sub-menu").show();

// listen to clicks from parent menu only
jQuery("#sub_nav ul li a").click(function() {

// if subpage is clicked, then open that link without doing anything
if ( jQuery(this).next("ul.sub-menu").length == 0){
return;
}

// hide all sub menu
jQuery("#sub_nav ul li ul.sub-menu").hide();

// un-hilite current menu
jQuery("#sub_nav ul li").removeClass("current_page_item");

// close opened_menu - to +
jQuery("#sub_nav ul li a span.opened_menu").html("+");
jQuery("#sub_nav ul li a span.opened_menu").removeClass("opened_menu");

// show the clicked submenu
jQuery(this).next("ul.sub-menu").fadeIn("slow");

// highlite current menu
jQuery(this).parent("li").addClass("current_page_item");

// change + to -
jQuery(this).children("span:first").html("-");
jQuery(this).children("span:first").addClass("opened_menu");

// if there's no next menu, then open that link
if ( jQuery(this).next("ul.sub-menu").length > 0){
return false;
}
});
});
</script>

Tested with safari 5.1 and working good!
It should work for you to as I didn't use any external plugin.. only the default jQuery code ;)

2011-09-20

ej_emman answers:

hello Priktop,

I have configure your problem. it works in me.

I can work on it. I will pm you my details.


priktop comments:

Cool, thanks!

2011-09-19

Romel Apuya answers:

hi have you tried using this?

[[LINK href="http://wordpress.org/extend/plugins/jquery-vertical-accordion-menu/"]]http://wordpress.org/extend/plugins/jquery-vertical-accordion-menu/[[/LINK]]


its easy to configure and is widgetized...


priktop comments:

Well thanks, it looks good but the problem is that my submenu's aren't custom menu's. They're dynamically generated. Or is there a way around that?


Romel Apuya comments:

hi sorry u already did used that one...
maybe there's just something u missed.
so it didnt work..i can help you with this..
i'll send you a PM.


Romel Apuya comments:

the javascript should run in noconflict mode.
already did the implementation on your site.
you can check it.


priktop comments:

Thanks but that really doesn't work well.

All the pages have a + sign in front of it, and they are all collapsed when a new page loads.
Also, the parent isn't highlighted when a subpage is active.

I'm gonna try Abdessamad Idrissi's solution now.


Romel Apuya comments:

the file that i edited is the header.php file.


priktop comments:

Ah ok so it is already Abdessamad's solution. That's too bad :(
Did your plugin-widget workaround not work?