-1

I'm encountering a problem while trying to switch and add classes to elements when a mouse click event occurs. Likewise I have multiple "li" elements. I want to add "class = subdrop active" to the selected anchor tag and the "class = active" to the subsequent li tag. I'm not sure if I'm handling the class manipulation correctly. Could someone please suggest the right approach?

<li class="submenu">
  <a href="javascript:void(0);">
    <i class="ti ti-layout-dashboard"></i>
    <span>Admin Profile</span>
    <span class="menu-arrow"></span>
  </a>
  <ul>
    <li>
      <a href="<?php echo base_url('admin_dashboard'); ?>">Dashboard</a>
    </li>
    <li>
      <a href="<?php echo base_url('admin_profile'); ?>">Profile</a>
    </li>
    <li>
      <a href="#">Settings</a>
    </li>
    <li>
      <a href="#">Contacts</a>
    </li>
  </ul>
</li>

Trying to get the following results on selected li clicks

<li class="submenu">
 <a href="javascript:void(0);" class="subdrop active"><i class="ti ti-layout-dashboard"></i><span>Admin Profile</span><span class="menu-arrow"></span>
</a>
<ul>
  <li><a href="<?php echo base_url('admin_dashboard'); ?>" class="active">Dashboard</a></li>
  <li><a href="<?php echo base_url('admin_profile'); ?>">Profile</a></li>
  <li><a href="#">Settings</a></li>
  <li><a href="#">Contacts</a></li>
</ul>
</li>
1
  • 1
    Please edit your question to include the code you're trying to use. Point out the difference between the expected and actual results Commented Apr 29 at 4:20

1 Answer 1

1

Hey there—this is something I’ve struggled with too. What worked for me was to keep two simple handlers: one for clicks on the top‐level and one for clicks on the submenu links. That way you never end up nesting or duplicating logic.

<ul>
  <li class="submenu">
    <a href="javascript:void(0);">
      <i class="ti ti-layout-dashboard"></i>
      <span>Admin Profile</span>
      <span class="menu-arrow"></span>
    </a>
    <ul>
      <li><a href="<?php echo base_url('admin_dashboard'); ?>">Dashboard</a></li>
      <li><a href="<?php echo base_url('admin_profile'); ?>">Profile</a></li>
      <li><a href="#">Settings</a></li>
      <li><a href="#">Contacts</a></li>
    </ul>
  </li>
  <!-- repeat for other .submenu items -->
</ul>

$(function(){
  // clicking the main menu title
  $(document).on('click', '.submenu > a', function(e){
    e.preventDefault();
    var $toggle  = $(this);
    var $parent  = $toggle.closest('.submenu');
    var $inner   = $toggle.next('ul');

    // close any other open submenu
    $('.submenu').not($parent).each(function(){
      $(this).children('a').removeClass('subdrop active');
      $(this).children('ul').slideUp(150);
    });

    // toggle the one we clicked
    $toggle.toggleClass('subdrop active');
    $inner.slideToggle(150);

    // if opening, give its first child link the active state
    if ($toggle.hasClass('active')) {
      $inner.find('a').removeClass('active');
      $inner.find('li:first > a').addClass('active');
    }
  });

  // clicking any child link
  $(document).on('click', '.submenu ul li a', function(e){
    e.preventDefault();
    var $link    = $(this);
    var $parent  = $link.closest('.submenu');
    var $toggle  = $parent.children('a');

    // clear all other child‐link highlights, then highlight this one
    $('.submenu ul li a').removeClass('active');
    $link.addClass('active');

    // make sure this submenu is open
    $('.submenu > a').not($toggle)
      .removeClass('subdrop active')
      .next('ul').slideUp(150);

    $toggle.addClass('subdrop active');
    $toggle.next('ul').slideDown(150);
  });
});

When you click the top‐level link, it first slams shut any other submenu, then toggles itself open/closed. Opening it also auto-selects the very first child item. Clicking a child link simply highlights that link, ensures its parent is open, and closes any other menus.

Sign up to request clarification or add additional context in comments.

2 Comments

Why preventDefault() on the sub <a> elements? They look like at least some of them should navigate normally
my bad, there’s no need to call e.preventDefault() on your real navigation links

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.