jquerymenuaccordion

Highlight parent menu when submenu is clicked in Jquery for accordion menu


$(document).ready(function() {

  // initialize accordion
  $('.acd ul').each(function() {
    var currentURI = window.location.href;
    var links = $('a', this);
    var collapse = true;
    for (var i = 0; i < links.size(); i++) {
      var elem = links.eq(i);
      var href = elem.attr('href');
      var hrefLength = href.length;
      var compareTo = currentURI.substr(-1 * hrefLength);
      if (href == compareTo) {
        collapse = false;
        break;
      }
    };
    if (collapse) {
      $(this).hide();
    }
  });

  // on click, show this element and hide all others
  $('.acd > li').click(function() {
    var me = $(this).children('ul');
    $('.acd ul').not(me).slideUp('normal');
    me.slideDown('normal');
  });
});
.acd,
.acd ul,
.acd li,
.acd a,
.acd span {
  margin: 0;
  padding: 0;
  border: none;
  outline: none;
  border-radius: 2px;
  -moz-border-radius: 2px;
  -webkit-border-radius: 2px;
}

.acd li {
  list-style: none;
}

.acd li>a {
  display: block;
  position: relative;
  min-width: 110px;
  padding: 0 10px 0 40px;
  color: #fdfdfd;
  font: bold 12px/32px Arial, sans-serif;
  text-decoration: none;
  text-shadow: 0px 1px 0px rgba(0, 0, 0, .35);
  background: #616975;
  background: -moz-linear-gradient(top, rgb(114, 122, 134) 0%, rgb(80, 88, 100) 100%);
  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, rgb(114, 122, 134)), color-stop(100%, rgb(80, 88, 100)));
  background: -webkit-linear-gradient(top, rgb(114, 122, 134) 0%, rgb(80, 88, 100) 100%);
  background: -o-linear-gradient(top, rgb(114, 122, 134) 0%, rgb(80, 88, 100) 100%);
  background: -ms-linear-gradient(top, rgb(114, 122, 134) 0%, rgb(80, 88, 100) 100%);
  background: linear-gradient(top, rgb(114, 122, 134) 0%, rgb(80, 88, 100) 100%);
  -webkit-box-shadow: inset 0px 1px 0px 0px rgba(255, 255, 255, .1), 0px 1px 0px 0px rgba(0, 0, 0, .1);
  -moz-box-shadow: inset 0px 1px 0px 0px rgba(255, 255, 255, .1), 0px 1px 0px 0px rgba(0, 0, 0, .1);
  box-shadow: inset 0px 1px 0px 0px rgba(255, 255, 255, .1), 0px 1px 0px 0px rgba(0, 0, 0, .1);
}

.acd li>a span {
  display: block;
  position: absolute;
  top: 7px;
  right: 0;
  padding: 0 10px;
  margin-right: 10px;
  font: normal bold 12px/18px Arial, sans-serif;
  background: #404247;
  -webkit-border-radius: 15px;
  -moz-border-radius: 15px;
  border-radius: 15px;
  -webkit-box-shadow: inset 1px 1px 1px rgba(0, 0, 0, .2), 1px 1px 1px rgba(255, 255, 255, .1);
  -moz-box-shadow: inset 1px 1px 1px rgba(0, 0, 0, .2), 1px 1px 1px rgba(255, 255, 255, .1);
  box-shadow: inset 1px 1px 1px rgba(0, 0, 0, .2), 1px 1px 1px rgba(255, 255, 255, .1);
}

.smenu li a {
  color: #878d95;
  text-shadow: 1px 1px 0px rgba(255, 255, 255, .2);
  background: #f2f2f2;
  border-bottom: 1px solid #d6d6d6;
  -webkit-box-shadow: inset 0px 1px 0px 0px rgba(255, 255, 255, .1), 0px 1px 0px 0px rgba(0, 0, 0, .1);
  -moz-box-shadow: inset 0px 1px 0px 0px rgba(255, 255, 255, .1), 0px 1px 0px 0px rgba(0, 0, 0, .1);
  box-shadow: inset 0px 1px 0px 0px rgba(255, 255, 255, .1), 0px 1px 0px 0px rgba(0, 0, 0, .1);
}

.smenu li:last-child a {
  border: none;
}

.smenu li>a span {
  color: #797979;
  text-shadow: 1px 1px 0px rgba(255, 255, 255, .2);
  background: transparent;
  border: 1px solid #c9c9c9;
  -webkit-box-shadow: none;
  -moz-box-shadow: none;
  box-shadow: none;
}

.smenu em {
  position: absolute;
  top: 0;
  left: 0;
  margin-left: 14px;
  color: #a6a6a6;
  font: normal 10px/32px Arial, sans-serif;
}

.acd>li:target>a,
.acd>li>a.active {
  color: #00121c;
  text-shadow: 1px 1px 1px rgba(255, 255, 255, .2);
  /*background: url(../img/active.png) repeat-x;*/
  background: #0088cd;
  background: -moz-linear-gradient(top, #0088cd 0%, #00669a 100%);
  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #0088cd), color-stop(100%, #00669a));
  background: -webkit-linear-gradient(top, #0088cd 0%, #00669a 100%);
  background: -o-linear-gradient(top, #0088cd 0%, #00669a 100%);
  background: -ms-linear-gradient(top, #0088cd 0%, #00669a 100%);
  background: linear-gradient(top, #0088cd 0%, #00669a 100%);
}

.smenu li:hover a {
  background: #f7f7f7;
}

.acd li>.smenu {
  display: block;
}

.acd li:target>.smenu {
  display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="acd">
  <li class="item1">
    <a href="#">Parent 1</a>
    <ul class="smenu">
      <li><a href="subpage1">Child 1</a></li>
      <li><a href="subpage2">Child 2</a></li>
    </ul>
  </li>
  <li class="item2">
    <a href="#">Parent 2</a>
    <ul class="smenu">
      <li><a href="subpage3">Child 1</a></li>
      <li><a href="subpage4">Child 2</a></li>
    </ul>
  </li>
</ul>

With reference to this question.

I wanted the accordion menu to drop down and highlight the parent when the child menu is clicked, the dropdown menu is supposed to remain open for the clicked link with parent li highlighted.

Currently dropdown of submenu remains open according to the current url. All I need to add now is to highlight the parent of the dropdown submenu. Can someone kindly assist me on this.

Thanks!


Solution

  • -> currently it is able to do so except that the link for the child seem to be disabled

    Because of : e.preventDefault(); Which has prevented the page to redirect to the url in anchor tag.


    -> i have subpages which have this menu on the left layout.

    When you are navigating to different pages with menu on each of them then either you will have to set the active class on each page yourself, so that when the page is loaded, menu is already active to indicate on which page you are.

    Or if you want to do it automatically then try this : http://jsfiddle.net/rd35goyt/1/ (cant be tested there)

    $('.smenu > li > a').on('click', function (e) {
        e.preventDefault();
        highlight($(this));
        window.location.href = $(this).prop('href') + "#" + $(this).prop("id");
    });
    function highlight($elem) {
        // reset previously sliding ul
        $('.acd > li > a.active').next('ul').slideUp();
        $('.acd > li > a').removeClass('active');
    
        $elem.closest('ul').prev('a').addClass('active');
        $elem.closest('ul').slideDown();
    }
    var type = window.location.hash.substr(1);
    highlight($("#"+type));
    

    html

    <ul class="acd">
        <li class="item1"> <a href="#">Parent 1</a>
    
            <ul class="smenu">
                <li><a href="subpage1" id="c1">Child 1</a>
                </li>
                <li><a href="subpage2" id="c2">Child 2</a>
                </li>
            </ul>
        </li>
        <li class="item2"> <a href="#">Parent 2</a>
    
            <ul class="smenu">
                <li><a href="subpage3" id="c3">Child 1</a>
                </li>
                <li><a href="subpage4" id="c4">Child 2</a>
                </li>
            </ul>
        </li>
    </ul>
    

    Notice : id for child links.

    It basically :

    1. Sends id of the child link clicked to the next sub-page.
    2. On the sub-page it extracts the id and calls highlight() function to highlight required parent.

    UPDATE

    $('.smenu > li > a').on('click', function (e) {
        e.preventDefault();
        highlight($(this));
        window.location.href = $(this).prop('href') + "#" + $(this).parent().prop("id");
    });
    function highlight($elem) {
        // reset previously sliding ul
        $('.acd > li > a.active').next('ul').slideUp();
        $('.acd > li > a').removeClass('active');
    
        $elem.closest('ul').prev('a').addClass('active');
        $elem.closest('ul').slideDown();
    }
    var type = window.location.hash.substr(1);
    highlight($("#" + type + " a"));
    

    html

    <ul class="acd">
        <li class="item1"> <a href="#">Parent 1</a>
    
            <ul class="smenu">
                <li id="c1"><a href="subpage1">Child 1</a>
                </li>
                <li id="c2"><a href="subpage2">Child 2</a>
                </li>
            </ul>
        </li>
        <li class="item2"> <a href="#">Parent 2</a>
    
            <ul class="smenu">
                <li id="c3"><a href="subpage3">Child 1</a>
                </li>
                <li id="c4"><a href="subpage4">Child 2</a>
                </li>
            </ul>
        </li>
    </ul>
    

    Notice : id for li.

    UPDATE

    For the lis without ul as child.

    http://jsfiddle.net/rd35goyt/2/

    $('.acd > li').click(function () {
        var me = $(this).children('ul');
        if(me.length===0){
            $(this).children().addClass("active");
            return;
        }
        $('.acd ul').not(me).slideUp('normal');
        me.slideDown('normal');
    
    });