javascriptjqueryjquery-uijquery-plugins

Issue with Switching and Adding Classes to Elements on Mouse Click


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>

Solution

  • 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.