1

I am building a wordpress website with drop down menu (sub menu).

enter image description here

To achieve this here I am using wordpress walker class. This is the code which I am using in my functions.php

class CSS_Menu_Maker_Walker extends Walker {

  var $db_fields = array( 'parent' => 'menu_item_parent', 'id' => 'db_id' );

  function start_lvl( &$output, $depth = 0, $args = array() ) {
    $indent = str_repeat("\t", $depth);
    $output .= "\n$indent<ul>\n";
  }

  function end_lvl( &$output, $depth = 0, $args = array() ) {
    $indent = str_repeat("\t", $depth);
    $output .= "$indent</ul>\n";
  }

  function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {

    global $wp_query;
    $indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';
    $class_names = $value = ''; 
    $classes = empty( $item->classes ) ? array() : (array) $item->classes;

    /* Add active class */
    if(in_array('current-menu-item', $classes)) {
      $classes[] = 'current';
      unset($classes['current-menu-item']);
    }

    /* Check for children */
    $children = get_posts(array('post_type' => 'nav_menu_item', 'nopaging' => true, 'numberposts' => 1, 'meta_key' => '_menu_item_menu_item_parent', 'meta_value' => $item->ID));
    if (!empty($children)) {
      $classes[] = 'has-children';
    }

    $class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item, $args ) );
    $class_names = $class_names ? ' class="' . esc_attr( $class_names ) . '"' : '';

    $id = apply_filters( 'nav_menu_item_id', 'menu-item-'. $item->ID, $item, $args );
    $id = $id ? ' id="' . esc_attr( $id ) . '"' : '';

    $output .= $indent . '<li' . $id . $value . $class_names .'>';

    $attributes  = ! empty( $item->attr_title ) ? ' title="'  . esc_attr( $item->attr_title ) .'"' : '';
    $attributes .= ! empty( $item->target )     ? ' target="' . esc_attr( $item->target     ) .'"' : '';
    $attributes .= ! empty( $item->xfn )        ? ' rel="'    . esc_attr( $item->xfn        ) .'"' : '';
    $attributes .= ! empty( $item->url )        ? ' href="'   . esc_attr( $item->url        ) .'"' : '';

    $item_output = $args->before;
    $item_output .= '<a'. $attributes .'>';
    $item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;
    $item_output .= '</a>';
    $item_output .= $args->after;

    $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
  }

  function end_el( &$output, $item, $depth = 0, $args = array() ) {
    $output .= "</li>\n";
  }
}

To try demonstrating what I am trying to accomplish please look at the follwoing HTML:

  <nav id="nav-wrap"> 

        <a class="mobile-btn" href="#nav-wrap" title="Show navigation">Show Menu</a>
           <a class="mobile-btn" href="#" title="Hide navigation">Hide Menu</a>

        <div class="row">                       

                <ul id="nav" class="nav">
                    <li class="current"><a href="index.html">Home</a></li>
                    <li class="has-children"><a href="#">Dropdown</a>
                      <ul>
                         <li><a href="#">Submenu 01</a></li>
                         <li><a href="#">Submenu 02</a></li>
                         <li><a href="#">Submenu 03</a></li>
                      </ul>
                   </li>
                   <li><a href="demo.html">Demo</a></li>    
                   <li><a href="archives.html">Archives</a></li>
                    <li class="has-children"><a href="single.html">Blog</a>
                            <ul>
                         <li><a href="blog.html">Blog Entries</a></li>
                         <li><a href="single.html">Single Blog</a></li>                      
                      </ul>
                    </li>               
                    <li><a href="page.html">Page</a></li>
                </ul> <!-- end #nav -->              

        </div> 

       </nav> <!-- end #nav-wrap --> 

Explanation:

  1. There is a main nav tag with a class called: "nav-wrap"
  2. Inside just a simple div tag with a class called: "row"
  3. Inside just a simple (ul li a) where ul tag of a class and id "nav"
  4. Drop Down wrapped with a div with a class called: "has-children"
  5. When a user clicks on any item the class "current" is called
  6. The class "current" is not called when a user clicks on any sub item. In, this case class "current" is applied on its parent. for e.g here when a user clicks on "Blog Entries" then class "current" is applied on its parent i.e "Blog"

enter image description here

But what I am actually getting is:

<nav id="nav-wrap"> 

        <a class="mobile-btn" href="#nav-wrap" title="Show navigation">Show Menu</a>
           <a class="mobile-btn" href="#" title="Hide navigation">Hide Menu</a>

                <div class="row"><ul id="nav" class="nav"><li id="menu-item-557" class="menu-item menu-item-type-custom menu-item-object-custom current-menu-item current_page_item menu-item-home current"><a href="http://127.0.0.1/wordpress/">Home</a></li>
<li id="menu-item-558" class="menu-item menu-item-type-post_type menu-item-object-page"><a href="http://127.0.0.1/wordpress/about-us/">About Us</a></li>
<li id="menu-item-559" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-has-children has-children"><a href="http://127.0.0.1/wordpress/blog/">Blog</a>
<ul>
    <li id="menu-item-564" class="menu-item menu-item-type-taxonomy menu-item-object-category"><a href="http://127.0.0.1/wordpress/blog/category/blogger/">Blogger</a></li>
    <li id="menu-item-565" class="menu-item menu-item-type-taxonomy menu-item-object-category"><a href="http://127.0.0.1/wordpress/blog/category/html-css/">HTML-CSS</a></li>
    <li id="menu-item-566" class="menu-item menu-item-type-taxonomy menu-item-object-category"><a href="http://127.0.0.1/wordpress/blog/category/psd/">PSD</a></li>
</ul>
</li>
<li id="menu-item-560" class="menu-item menu-item-type-post_type menu-item-object-page"><a href="http://127.0.0.1/wordpress/contact-us/">Contact</a></li>
</ul></div> 

       </nav> <!-- end #nav-wrap --> 

This is the code which I am using to output my menu in header.php

<nav id="nav-wrap"> 

        <a class="mobile-btn" href="#nav-wrap" title="Show navigation">Show Menu</a>
           <a class="mobile-btn" href="#" title="Hide navigation">Hide Menu</a>

                <?php wp_nav_menu(array(
                      'menu' => 'Main Navigation', 
                      'menu_class'      => 'nav',
                      'menu_id'         => 'nav',
                      'container_class' => 'row', 
                      'walker' => new CSS_Menu_Maker_Walker()
                )); ?> 

       </nav> <!-- end #nav-wrap -->

enter image description here

But, the problem is it's also applying "current" class when I click on any sub-item which I don't want. So, what should I do to remove "current" class in a submenu item and apply that on its parent class.

This is the template which I am converting in wp.

  • How did you go with this? Don't forget to come back and accept an answer (by clicking the check mark on the left of an answer) if it helped you! – Tim Malone Jul 7 '16 at 6:31
1

Use following code as jQuery:

jQuery('#nav li').removeClass('current');
jQuery('#nav>li.current-menu-item').addClass('current');
jQuery('.has-children li.current-menu-item').closest('.has-children').addClass('current');

See jsfiddle (current item red color). When you click "Single Blog" menu item your html structure will like my following example and jQuery will remove class active from it and add class it's parent exactly like what you wanted. https://jsfiddle.net/dom8188s/

0

@raunak how about use jQuery jQuery(" ul li .menu-item").removeClass( "current" ); for adding to parent jQuery(".current-menu-parent").addClass( "current" );

  • tried but not working... :-/ – Raunak Hajela Mar 16 '15 at 11:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.