tibewww
tibewww

Reputation: 603

Accordion menu jquery doesn't work

I'm trying to achieve an accordion menu in jquery,

However it doesn't seem to work, and my submenu doesnt appear . ..

I've try various possibility by changing my jquery but nothing to do :(,

any help would be amazing !!

I attach my code below:

html:

 <div class="content-left">
    <ul id="accordion" class="level-1">

        <li><a href="#" class="ext1"><span class="icons1"><small>ELECTRICAL</small></span></a>
            <ul id="sub-menu" class="level-2 drop1 pt10">
<li>test</li>
<li>test</li>
<li>test</li>
<li>test</li>


            </ul>
        </li>

        <li><a href="#" class="ext2"><span class="icons2"><small>HOME & GARDEN</small></span></a>
            <ul id="sub-menu" class="level-2 drop2 pt10">
<li>test</li>
<li>test</li>
<li>test</li>
<li>test</li>            </ul>
        </li>

        <li><a href="#" class="ext3"><span class="icons3"><small>PETS AND LIVESTOCK</small></span></a>
            <ul id="sub-menu" class="level-2 drop3 pt10">
<li>test</li>
<li>test</li>
<li>test</li>
<li>test</li>            </ul>
        </li>

        <li><a href="#" class="ext4"><span class="icons4"><small>PROPERTY</small></span></a>
            <ul id="sub-menu" class="level-2 drop4 pt10">
<li>test</li>
<li>test</li>
<li>test</li>
<li>test</li>            </ul>
        </li>

        <li><a href="#" class="ext5"><span class="icons5"><small>BUSINESS AND LOANS </small></span></a>
            <ul id="sub-menu" class="level-2 drop5 pt10">
<li>test</li>
<li>test</li>
<li>test</li>
<li>test</li>            </ul>
        </li>

       </div>

Jquery:

 <script type="text/javascript">

    ( function( $ ) {
$( document ).ready(function() {
$('#content-left ul#accordion.level-1').on('click', function(){
        $(this).removeAttr('href');
        var element = $(this).parent('li');
        if (element.hasClass('level-2')) {
            element.removeClass('level-2');
            element.find('li').removeClass('level-2');
            element.find('ul').slideUp();
        }
        else {
            element.addClass('level-2');
            element.children('ul').slideDown();
            element.siblings('li').children('ul').slideUp();
            element.siblings('li').removeClass('level-2');
            element.siblings('li').find('li').removeClass('level-2');
            element.siblings('li').find('ul').slideUp();
        }
    });
});
} )( jQuery );
    </script>

CSS:

 #accordion ul.level-2, #accordion ul.level-3 {
        display: none;
    }

    #accordion ul.active {
        display: block;
    }

OR the JSFIDDLE: https://jsfiddle.net/8x7rjhz9/1/

Thank you for your time and advise in this !

---EDIT ---

How can i do it for three levels and let the stay active on click on an item list ?

3 LEVELS:

   <div class="content-left">
    <ul id="accordion" class="level-1">

        <li><a href="#" class="ext1"><span class="icons1"><small>ELECTRICAL</small></span></a>
            <ul id="sub-menu" class="level-2 drop1 pt10">
<li>test</li>
<ul id="sub-menu" class="level-3 drop11">
    <li><a href="#">sub sub</a></li>
    <li><a href="#">sub sub</a></li>
    <li><a href="#">sub sub</a></li>
</ul>
<li>test</li>
<li>test</li>
<li>test</li>


            </ul>
        </li>

        <li><a href="#" class="ext2"><span class="icons2"><small>HOME & GARDEN</small></span></a>
            <ul id="sub-menu" class="level-2 drop2 pt10">
<li>test</li>
<li>test</li>
<li>test</li>
<li>test</li>            </ul>
        </li>

        <li><a href="#" class="ext3"><span class="icons3"><small>PETS AND LIVESTOCK</small></span></a>
            <ul id="sub-menu" class="level-2 drop3 pt10">
<li>test</li>
<li>test</li>
<li>test</li>
<li>test</li>            </ul>
        </li>

        <li><a href="#" class="ext4"><span class="icons4"><small>PROPERTY</small></span></a>
            <ul id="sub-menu" class="level-2 drop4 pt10">
<li>test</li>
<li>test</li>
<li>test</li>
<li>test</li>            </ul>
        </li>

        <li><a href="#" class="ext5"><span class="icons5"><small>BUSINESS AND LOANS </small></span></a>
            <ul id="sub-menu" class="level-2 drop5 pt10">
<li>test</li>
<li>test</li>
<li>test</li>
<li>test</li>            </ul>
        </li>

       </div>

JS:

<script type="text/javascript">
    ( function( $ ) {
$( document ).ready(function() {
$('ul#accordion.level-1 li').on('click', function(){

        var element = $(this);
        if (element.hasClass('level-2')) {
            element.removeClass('level-2');
            element.find('ul').slideUp();
        }
        else {
            element.addClass('level-2');
            element.children('ul').slideDown();
            element.siblings('li').children('ul').slideUp();
            element.siblings('li').removeClass('level-2');
        }
    });
});
} )( jQuery );

NEW JSFIDDLE: https://jsfiddle.net/430az1j4/5/

</script>

--- EDIT 3 PHP ----

I'm calling my third level category by php this way:

<?
$cats = array();

foreach (AdCategory::getList(array('filter' => array('parent_id' => null))) as $category){

    $subcats = AdCategory::getList(array('filter' => array('parent_id' => $category->id, 'ha' => 1)));

    if($category->exclude == 0){
        $cats[$category->name] = '';
        //$cats["main_path"] = $category->path_url_static;

        $this_cat = array_chunk($subcats, 10);

        foreach($this_cat as $chunk) {
            foreach($chunk as $subcat) { 

                if (strcmp($subcat->name , "Sub cat 1") == 0) {
                    $cats[$category->name] .= '<li><a href="'.$subcat->path_url.'">'.$subcat->name.'</a>';
                    $cats[$category->name] .= '<ul id="sub-menu" class="level-3 drop11">
                    <li><a href="/path">sub sub</a></li>
                    <li><a href="/path">sub sub</a></li>
                    <li><a href="/path">sub sub</a></li>
                    <li class="pad_last"><a href="/path">Other</a></li>
                    </ul>
                    </li>'; 

                } else if (strcmp($subcat->name , "sub cat 2") == 0) {
                    $cats[$category->name] .= '<li><a href="'.$subcat->path_url.'">'.$subcat->name.'</a>';
                    $cats[$category->name] .= '<ul id="sub-menu" class="level-3 drop11">
                    <li><a href="/path">sub sub</a></li>
                    <li><a href="/path">sub sub</a></li>
                    <li><a href="/path">sub sub</a></li>
                    <li class="pad_last"><a href="path">Other</a></li></ul></li>';
                } 

                else {
                    $cats[$category->name] .= '<li><a href="'.$subcat->path_url.'">'.$subcat->name.'</a></li>'; 
                }

            }

        }
    }
    if (array_key_exists($category->name, $cats))
       $cats[$category->name] .= '<div class="clear"></div>';

}

?>

In fact - there are not in the html - it build this way for the two first level:

<div class="content-left">
    <ul id="accordion" class="level-1">

        <li><a href="#" class="ext1"><span class="icons1"><small>main 1</small></span></a>
            <ul id="sub-menu" class="level-2 drop1 pt10">
                 <?=$cats['catname1']?>
            </ul>
        </li>

        <li><a href="#" class="ext2"><span class="icons2"><small>main 2</small></span></a>
            <ul id="sub-menu" class="level-2 drop2 pt10">
                <?=$cats['catname2']?>
            </ul>
        </li>

        <li><a href="#" class="ext3"><span class="icons3"><small>main 3 </small></span></a>
            <ul id="sub-menu" class="level-2 drop3 pt10">
                <?=$cats['catname3']?>
            </ul>
        </li>

        <li><a href="/property" class="ext4"><span class="icons4"><small>main 4</small></span></a>
            <ul id="sub-menu" class="level-2 drop4 pt10">
               <?=$cats['catname4']?>
            </ul>
        </li>

    </ul>

Upvotes: 1

Views: 315

Answers (5)

Ramanathan Muthuraman
Ramanathan Muthuraman

Reputation: 752

By editing few lines in your script, the accordion effect can be achieved

( function( $ ) {
$( document ).ready(function() {
$('ul#accordion.level-1 li').on('click', function(){

        var element = $(this);
        if (element.hasClass('level-2')) {
            element.removeClass('level-2');
            element.find('ul').slideUp();
        }
        else {
            element.addClass('level-2');
            element.children('ul').slideDown();
            element.siblings('li').children('ul').slideUp();
            element.siblings('li').removeClass('level-2');
        }
    });
});
} )( jQuery );

JS fiddle link : https://jsfiddle.net/430az1j4/4/

Upvotes: 1

Avinash Perla
Avinash Perla

Reputation: 193

there are mainly two problems in your code

1) selector 2) haven't used preventDefault() function

I have updated the code check this

    <div class="content-left">
    <ul id="accordion" class="level-1">

        <li><a href="#" class="ext1"><span class="icons1"><small>ELECTRICAL</small></span></a>
            <ul id="sub-menu" class="level-2 drop1 pt10">
<li>test</li>
<li>test</li>
<li>test</li>
<li>test</li>


            </ul>
        </li>

        <li><a href="#" class="ext2"><span class="icons2"><small>HOME & GARDEN</small></span></a>
            <ul id="sub-menu" class="level-2 drop2 pt10">
<li>test</li>
<li>test</li>
<li>test</li>
<li>test</li>            </ul>
        </li>

        <li><a href="#" class="ext3"><span class="icons3"><small>PETS AND LIVESTOCK</small></span></a>
            <ul id="sub-menu" class="level-2 drop3 pt10">
<li>test</li>
<li>test</li>
<li>test</li>
<li>test</li>            </ul>
        </li>

        <li><a href="#" class="ext4"><span class="icons4"><small>PROPERTY</small></span></a>
            <ul id="sub-menu" class="level-2 drop4 pt10">
<li>test</li>
<li>test</li>
<li>test</li>
<li>test</li>            </ul>
        </li>

        <li><a href="#" class="ext5"><span class="icons5"><small>BUSINESS AND LOANS </small></span></a>
            <ul id="sub-menu" class="level-2 drop5 pt10">
<li>test</li>
<li>test</li>
<li>test</li>
<li>test</li>            </ul>
        </li>

       </div>


( function( $ ) {
$( document ).ready(function() {
$('#accordion.level-1 a').on('click', function(e){
        e.preventDefault();
        $(this).removeAttr('href');
        var element = $(this).parent('li');
        if (element.hasClass('level-2')) {
            element.removeClass('level-2');
            element.find('li').removeClass('level-2');
            element.find('ul').slideDown();
        }
        else {
            element.addClass('level-2');
            element.children('ul').slideDown();
            element.siblings('li').children('ul').slideUp();
            element.siblings('li').removeClass('level-2');
            element.siblings('li').find('li').removeClass('level-2');
            element.siblings('li').find('ul').slideDown();
        }
    });
});
} )( jQuery );

https://jsfiddle.net/8x7rjhz9/2/

Upvotes: 1

Arun P Johny
Arun P Johny

Reputation: 388436

You can try

jQuery(function ($) {
    $('#accordion.level-1 li:has(.sub-menu) > a').on('click', function () {
        var $li = $(this).closest('li');
        if ($li.hasClass('active')) {
            $li.find('.sub-menu').stop().slideUp();
            $li.find('li.active').removeClass('active');
        } else {
            $li.children('.sub-menu').stop().slideDown();
            $('#accordion li.active').removeClass('active').children('.sub-menu').stop().slideUp();
        }
        $li.toggleClass('active')
    });
});

Demo: Fiddle

Also note that, since ID of an element must be unique I've changed sub-menu to a class.

Upvotes: 0

Gurpreet Khattra
Gurpreet Khattra

Reputation: 111

try following code or visit https://jqueryui.com/accordion/

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>jQuery UI Accordion - Default functionality</title>
  <link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
  <script src="//code.jquery.com/jquery-1.10.2.js"></script>
  <script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
  <link rel="stylesheet" href="/resources/demos/style.css">
  <script>
  $(function() {
    $( "#accordion" ).accordion();
  });
  </script>
</head>
<body>
 
<div id="accordion">
  <h3>Section 1</h3>
  <div>
    <p>
    Mauris mauris ante, blandit et, ultrices a, suscipit eget, quam. Integer
    ut neque. Vivamus nisi metus, molestie vel, gravida in, condimentum sit
    amet, nunc. Nam a nibh. Donec suscipit eros. Nam mi. Proin viverra leo ut
    odio. Curabitur malesuada. Vestibulum a velit eu ante scelerisque vulputate.
    </p>
  </div>
  <h3>Section 2</h3>
  <div>
    <p>
    Sed non urna. Donec et ante. Phasellus eu ligula. Vestibulum sit amet
    purus. Vivamus hendrerit, dolor at aliquet laoreet, mauris turpis porttitor
    velit, faucibus interdum tellus libero ac justo. Vivamus non quam. In
    suscipit faucibus urna.
    </p>
  </div>
  <h3>Section 3</h3>
  <div>
    <p>
    Nam enim risus, molestie et, porta ac, aliquam ac, risus. Quisque lobortis.
    Phasellus pellentesque purus in massa. Aenean in pede. Phasellus ac libero
    ac tellus pellentesque semper. Sed ac felis. Sed commodo, magna quis
    lacinia ornare, quam ante aliquam nisi, eu iaculis leo purus venenatis dui.
    </p>
    <ul>
      <li>List item one</li>
      <li>List item two</li>
      <li>List item three</li>
    </ul>
  </div>
  <h3>Section 4</h3>
  <div>
    <p>
    Cras dictum. Pellentesque habitant morbi tristique senectus et netus
    et malesuada fames ac turpis egestas. Vestibulum ante ipsum primis in
    faucibus orci luctus et ultrices posuere cubilia Curae; Aenean lacinia
    mauris vel est.
    </p>
    <p>
    Suspendisse eu nisl. Nullam ut libero. Integer dignissim consequat lectus.
    Class aptent taciti sociosqu ad litora torquent per conubia nostra, per
    inceptos himenaeos.
    </p>
  </div>
</div>
 
 
</body>
</html>

Upvotes: 0

Michael Giovanni Pumo
Michael Giovanni Pumo

Reputation: 14784

I think you would be better off utilising jQuery UI's accordion module:

Include the script tag to jQuery UI:

<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>

Use this format of HTML code:

<div id="accordion">
  <h3>Section 1</h3>
  <div>
    <p>
    Mauris mauris ante, blandit et, ultrices a, suscipit eget, quam. Integer
    ut neque. Vivamus nisi metus, molestie vel, gravida in, condimentum sit
    amet, nunc. Nam a nibh. Donec suscipit eros. Nam mi. Proin viverra leo ut
    odio. Curabitur malesuada. Vestibulum a velit eu ante scelerisque vulputate.
    </p>
  </div>
  <h3>Section 2</h3>
  <div>
    <p>
    Sed non urna. Donec et ante. Phasellus eu ligula. Vestibulum sit amet
    purus. Vivamus hendrerit, dolor at aliquet laoreet, mauris turpis porttitor
    velit, faucibus interdum tellus libero ac justo. Vivamus non quam. In
    suscipit faucibus urna.
    </p>
  </div>
  <h3>Section 3</h3>
  <div>
    <p>
    Nam enim risus, molestie et, porta ac, aliquam ac, risus. Quisque lobortis.
    Phasellus pellentesque purus in massa. Aenean in pede. Phasellus ac libero
    ac tellus pellentesque semper. Sed ac felis. Sed commodo, magna quis
    lacinia ornare, quam ante aliquam nisi, eu iaculis leo purus venenatis dui.
    </p>
    <ul>
      <li>List item one</li>
      <li>List item two</li>
      <li>List item three</li>
    </ul>
  </div>
  <h3>Section 4</h3>
  <div>
    <p>
    Cras dictum. Pellentesque habitant morbi tristique senectus et netus
    et malesuada fames ac turpis egestas. Vestibulum ante ipsum primis in
    faucibus orci luctus et ultrices posuere cubilia Curae; Aenean lacinia
    mauris vel est.
    </p>
    <p>
    Suspendisse eu nisl. Nullam ut libero. Integer dignissim consequat lectus.
    Class aptent taciti sociosqu ad litora torquent per conubia nostra, per
    inceptos himenaeos.
    </p>
  </div>
</div>

Attach the script like so:

(function($) {
    $( "#accordion" ).accordion();
})(jQuery);

See this page for more information: https://jqueryui.com/accordion/

Upvotes: 0

Related Questions