SitePoint Sponsor

User Tag List

Results 1 to 11 of 11
  1. #1
    SitePoint Enthusiast
    Join Date
    Mar 2011
    Posts
    90
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    JavaScript list of links with sub lists, hide and show

    Hey guys, I am trying to set up a list of links for a list of products in my sidebar, where a user clicks on one category then a sub set of links will appear under the main list link, clicking on any other category closes the previous set of links and opens the new sub set. I tried to do this with PHP but due to using PHP include for my sidebar I ended up with multiple PHP files, not good.I also think that creating this function should be client side, I hope I am right. I do not even know if this could be done in JavaScript, any suggestion on this would be appreciated!

    I don't know how to write JavaScript to work with the sidebar.php file which I am including for every page in the sidebar div in the HTML, its really confusing me.

    Many thanks!!

  2. #2
    Under Construction silver trophybronze trophy AussieJohn's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, Australia
    Posts
    776
    Mentioned
    11 Post(s)
    Tagged
    0 Thread(s)
    It would be relatively easy to do this in JavaScript and even quicker if we use the jQuery library along with it.

    A working example of the below code can be seen at: http://jsfiddle.net/GeekyJohn/9kaQQ/

    If you had some basic markup like an unordered list for the navigation:
    Code HTML4Strict:
    <ul id="nav">    
        <li>
            <a href="#">Section</a>
            <ul>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
            </ul>
        </li>
        <li>
            <a href="#">Section</a>
            <ul>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
            </ul>
        </li>
        <li>
            <a href="#">Section</a>
            <ul>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
            </ul>
        </li>
    </ul>
    Together with some very very basic CSS, you can of course expand on this to make it look nicer.
    Code CSS:
    body {
        padding:20px;
    }
    .open {
        display:block;
    }
    ul ul {
        margin-left:20px;
    }

    Now we can get to the good part. The jQuery that will take care of it.

    This snippet emulates the basic functionality of the jQuery Accordion (which is pretty much the functionality you described , of course this snippet is a little shorter than the jQuery Accordion script)

    Hopefully the comments will explain enough, let me know if any of it isn't clear.
    Code JavaScript:
    //get a reference to the nav <ul>
    $nav = $("#nav");
     
     
    //hide all but the first sub list
    $nav.find("ul:not(:first)").hide();
     
     
    //mark the first sub list as open
    $nav.find("ul:first").addClass("open");
     
     
    //receive clicks on the section links
    $nav.on("click", "#nav>li>a", function(e){
     
     
        //get a reference to the currently clicked link and its list item
        $this = $(this);
        $currentLi = $this.closest("li");
     
        //if our current section is open, just return
        if ($currentLi.find(".open").is("ul")) {
            //if you want a section link to be able to collapse itself, uncomment this line:
            //$currentLi.find("ul.open").slideUp().removeClass("open")
     
            return; 
        }
     
     
        //close all open lists
        $nav.find("ul.open").slideUp().removeClass("open");
     
        //open the submenu that belongs to this section
        $currentLi.find("ul").slideDown().addClass("open");
     
     
    });
    var details = {
    . . web: "afterlight.com.au",
    . . photos: "jvdl.id.au",
    . . psa: "usethelatestversion.com"
    }

  3. #3
    SitePoint Enthusiast
    Join Date
    Mar 2011
    Posts
    90
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Aussie John, many thanks for that example code, I am this minute about to test it all out and see if I can use it to do what I want! Thanks a lot for this, I shall let you know how I get on!

    Cheers!

  4. #4
    SitePoint Member
    Join Date
    Apr 2013
    Posts
    3
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Am I missing a step? I am using the exact example Aussie John provided. I am trying to replicate deucalion0's process as I have a similar request. Thank you.

    HTML Code:
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Untitled Document</title>
    <link href="test.css" rel="stylesheet" type="text/css">
    </head>
    
    <body>
    <script type="text/javascript" src="test.js">
    <ul id="nav">
        <li>
            <a href="#">Section</a>
            <ul>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
            </ul>
        </li>
        <li>
            <a href="#">Section</a>
            <ul>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
            </ul>
        </li>
        <li>
            <a href="#">Section</a>
            <ul>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
            </ul>
        </li>
        <li>
            <a href="#">Section</a>
            <ul>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
            </ul>
        </li>
        <li>
            <a href="#">Section</a>
            <ul>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
            </ul>
        </li>
    </ul></script>
    </body>
    </html>

  5. #5
    Under Construction silver trophybronze trophy AussieJohn's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, Australia
    Posts
    776
    Mentioned
    11 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by yaknows View Post
    Am I missing a step? I am using the exact example Aussie John provided. I am trying to replicate deucalion0's process as I have a similar request. Thank you.

    HTML Code:
    <script type="text/javascript" src="test.js">
    <ul id="nav">
    ...
    </ul></script>
    I think the trouble here might be that you've put all your markup inside a script tag. Try placing the closing script tag at the end of the opening one and then moving the entire script tag to just before the closing body tag.

    HTML Code:
    <ul id="nav">
    ...
    </ul>
    
    <script type="text/javascript" src="test.js"></script>
    </body>
    var details = {
    . . web: "afterlight.com.au",
    . . photos: "jvdl.id.au",
    . . psa: "usethelatestversion.com"
    }

  6. #6
    SitePoint Member
    Join Date
    Apr 2013
    Posts
    3
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thank you for your response!! Hmm... So I followed your directions, I even added the css and js into the page, still nothing happening...?

    Code:
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Untitled Document</title>
    <style type="text/css">
    body {
        padding:20px;
    }
    .open {
        display:block;
    }
    ul ul {
        margin-left:20px;
    }
    </style>
    </head>
    
    <body>
    <ul id="nav">
        <li>
            <a href="#">Section</a>
            <ul>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
            </ul>
        </li>
        <li>
            <a href="#">Section</a>
            <ul>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
            </ul>
        </li>
        <li>
            <a href="#">Section</a>
            <ul>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
            </ul>
        </li>
        <li>
            <a href="#">Section</a>
            <ul>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
            </ul>
        </li>
        <li>
            <a href="#">Section</a>
            <ul>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
            </ul>
        </li>
    </ul><script type="text/javascript">
    //get a reference to the nav <ul>
    $nav = $("#nav");
    
    //hide all but the first sub list
    $nav.find("ul:not(:first)").hide();
    
    //mark the first sub list as open
    $nav.find("ul:first").addClass("open");
    
    //receive clicks on the section links
    $nav.on("click", "#nav>li>a", function(e) {
    
        //get a reference to the currently clicked link and its list item
        $this = $(this);
        $currentLi = $this.closest("li");
    
        //if our current section is open, just return
        if ($currentLi.find(".open").is("ul")) {
            //if you want a section link to be able to collapse itself, uncomment this line:
            $currentLi.find("ul.open").slideUp().removeClass("open")
            return;
        }
    
        //close all open lists
        $nav.find("ul.open").slideUp().removeClass("open");
    
        //open the submenu that belongs to this section
        $currentLi.find("ul").slideDown().addClass("open");
    
    });// JavaScript Document</script>
    </body>
    </html>

  7. #7
    Under Construction silver trophybronze trophy AussieJohn's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, Australia
    Posts
    776
    Mentioned
    11 Post(s)
    Tagged
    0 Thread(s)
    Ah, right, you'll also need to include jQuery.
    Put this line above your first <script> section and things should start working
    Code:
    <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
    var details = {
    . . web: "afterlight.com.au",
    . . photos: "jvdl.id.au",
    . . psa: "usethelatestversion.com"
    }

  8. #8
    SitePoint Member
    Join Date
    Apr 2013
    Posts
    3
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Still nothing..
    Code:
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Untitled Document</title>
    <style type="text/css">
    body {
        padding:20px;
    }
    .open {
        display:block;
    }
    ul ul {
        margin-left:20px;
    }
    </style>
    </head>
    
    <body>
    <ul id="nav">
        <li>
            <a href="#">Section</a>
            <ul>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
            </ul>
        </li>
        <li>
            <a href="#">Section</a>
            <ul>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
            </ul>
        </li>
        <li>
            <a href="#">Section</a>
            <ul>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
            </ul>
        </li>
        <li>
            <a href="#">Section</a>
            <ul>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
            </ul>
        </li>
        <li>
            <a href="#">Section</a>
            <ul>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
            </ul>
        </li>
    </ul>
    <script src="jquery.js"></script>
    <script type="text/javascript">
    //get a reference to the nav <ul>
    $nav = $("#nav");
    
    //hide all but the first sub list
    $nav.find("ul:not(:first)").hide();
    
    //mark the first sub list as open
    $nav.find("ul:first").addClass("open");
    
    //receive clicks on the section links
    $nav.on("click", "#nav>li>a", function(e) {
    
        //get a reference to the currently clicked link and its list item
        $this = $(this);
        $currentLi = $this.closest("li");
    
        //if our current section is open, just return
        if ($currentLi.find(".open").is("ul")) {
            //if you want a section link to be able to collapse itself, uncomment this line:
            $currentLi.find("ul.open").slideUp().removeClass("open")
            return;
        }
    
        //close all open lists
        $nav.find("ul.open").slideUp().removeClass("open");
    
        //open the submenu that belongs to this section
        $currentLi.find("ul").slideDown().addClass("open");
    
    });// JavaScript Document</script>
    </body>
    </html>

  9. #9
    Under Construction silver trophybronze trophy AussieJohn's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, Australia
    Posts
    776
    Mentioned
    11 Post(s)
    Tagged
    0 Thread(s)
    Ok so this was kind of interesting

    I took your code and tried to run it, and indeed nothing happened when clicking on the links.

    I had a look at my example on JSFiddle and confirmed everything was working.

    While looking there, I noticed that it was using an older version of jQuery (1.7.1) and of course locally I did a quick test with the latest version, as you undoubtedly did. Alas, things didn't work in the latest version.

    The issue lies around how the event delegate method .on() interprets its second parameter, the child selector which should be monitored for the events. In jQuery 1.7.1 you could still reference the parent element that the event was bound on, but somewhere along the way to 1.9.1 that must have been fixed.

    Long story short, if you update the following line:
    Code JavaScript:
    //receive clicks on the section links
    $nav.on("click", "#nav>li>a", function(e) {

    And change it to:
    Code JavaScript:
    //receive clicks on the section links
    $nav.on("click", ">li>a", function(e) {

    Now things should start working

    (The ">" at the start of the selector is intentional)


    The Fiddle has been updated as well: http://jsfiddle.net/GeekyJohn/9kaQQ/
    var details = {
    . . web: "afterlight.com.au",
    . . photos: "jvdl.id.au",
    . . psa: "usethelatestversion.com"
    }

  10. #10
    SitePoint Member
    Join Date
    Apr 2013
    Posts
    3
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    still nothing... :\
    Code:
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Untitled Document</title>
    <style type="text/css">
    body {
        padding:20px;
    }
    .open {
        display:block;
    }
    ul ul {
        margin-left:20px;
    }
    </style>
    </head>
    
    <body>
    <ul id="nav">
        <li>
            <a href="#">Section</a>
            <ul>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
            </ul>
        </li>
        <li>
            <a href="#">Section</a>
            <ul>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
            </ul>
        </li>
        <li>
            <a href="#">Section</a>
            <ul>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
            </ul>
        </li>
        <li>
            <a href="#">Section</a>
            <ul>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
            </ul>
        </li>
        <li>
            <a href="#">Section</a>
            <ul>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
                <li><a href="#">Product</a></li>
            </ul>
        </li>
    </ul>
    <script src="jquery.js" type="text/javascript"></script>
    <script type="text/javascript">
    //get a reference to the nav <ul>
    $nav = $("#nav");
    
    //hide all but the first sub list
    $nav.find("ul:not(:first)").hide();
    
    //mark the first sub list as open
    $nav.find("ul:first").addClass("open");
    
    //receive clicks on the section links
    $nav.on("click", ">li>a", function(e) {
    
        //get a reference to the currently clicked link and its list item
        $this = $(this);
        $currentLi = $this.closest("li");
    
        //if our current section is open, just return
        if ($currentLi.find(".open").is("ul")) {
            //if you want a section link to be able to collapse itself, uncomment this line:
            $currentLi.find("ul.open").slideUp().removeClass("open")
            return;
        }
    
        //close all open lists
        $nav.find("ul.open").slideUp().removeClass("open");
    
        //open the submenu that belongs to this section
        $currentLi.find("ul").slideDown().addClass("open");
    
    });// JavaScript Document</script>
    </body>
    </html>

  11. #11
    Under Construction silver trophybronze trophy AussieJohn's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, Australia
    Posts
    776
    Mentioned
    11 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by yaknows View Post
    still nothing... :\
    If I copy that code verbatim and put it in a HTML file, everything seems to work just fine. Can you double check that it is actually loading the jQuery script in?

    If in doubt, replace your reference to jQuery with the following:
    Code:
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
    var details = {
    . . web: "afterlight.com.au",
    . . photos: "jvdl.id.au",
    . . psa: "usethelatestversion.com"
    }


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •