SitePoint Sponsor

User Tag List

Results 1 to 8 of 8
  1. #1
    SitePoint Evangelist CyberFuture's Avatar
    Join Date
    May 2001
    Location
    San Diego, CA
    Posts
    434
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    jQuery Accordian Menu behavior problem

    My leftside Nav is working almost perfectly. The main remaing problem is that when you click on a top level a category (the actual category name, not the triangle) you are taken that category and that category opens up on the leftside nav. I have a sample page setup where pom poms have been selected (li contains class=selected), but it's cheerleading uniforms thats opened up.
    http://www.omnicheer\test\index.html

    For the life of me I can't figure out why this is happening. The bahavior works perfectly on the sub categories and sub-sub categories. Please help. Thanks.

    Here's the HTML/CSS:
    Code:
    <!DOCTYPE HTMLPUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
    <html>
        <head>
            <title>Pom Poms</title>
            <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
            <META NAME='keywords' CONTENT=''>
            <META NAME='description' CONTENT=''>
            <script type="text/javascript" src="accordion4/jquery.pack.js"></script>
            <script type="text/javascript" src="accordion4/jquery.easing.1.3.js"></script>
            <script type="text/javascript" src="accordion4/leftNavMenu.js"></script>
        <style type="text/css">
    <!--
    * {
        margin:0; 
        padding:0;  
        font-family:Arial, Helvetica, sans-serif;
        font-size:11px;
        color:#666;
        }
    #leftnav {
    width:160px;
    margin:0 5px 25px 0;
    float:left;
    text-align: left;
    }
    /* Category tree */
    ul.tree, ul.tree ul{ list-style-type:none; }
    ul.tree li{
            padding-left:7px;
            margin-left:5px;
    }
    ul.tree a{ padding-left:2px; text-decoration:none; border:none; }
    ul.tree a.selected{ font-weight:bold; }
    #leftNavMenu {
            padding:0.5em 0.7em 0pt;
            background-color: #fff;
            min-height:20px;
    }
    #leftNavMenu ul.tree { padding-left:0.5em; }
    #leftNavMenu ul.dhtml{ display:none; }
    #leftNavMenu ul.tree li {
            border: none;
            padding-left:15px;
            margin-left:0;
            font-weight:bold;
            font-size:13px;
            line-height:13px;
            margin-top:2px;
    }
    #leftNavMenu ul.tree li ul li{
            padding-left:15px;
            background:none;
            font-size:11px;
            font-weight:normal;
    }
    #leftNavMenu ul.tree li ul li ul li{
            padding-left:15px;
            font-size:9px;
    }
    #leftNavMenu ul.tree a{
            padding-left:0;
            color:#888;
    }
    div#leftNavMenu ul.tree a:hover{
            text-decoration:none;
            color:#cc3399;
    }
    div#leftNavMenu ul.tree a.selected{
            color: #888;
            font-weight: bold;
    }
    div#leftNavMenu span.grower{
            display:block;
            float:left;
            background-position: 0px 3px;
            background-repeat: no-repeat;
            width:14px;
            height:15px;
            margin: 0 0 0 -15px!important;
            margin: 0 0 0 -6px;
            padding: 0;
    }
    div#leftNavMenu span.OPEN { 
    background-image: url(contract.gif);
    cursor:pointer;
    }
    div#leftNavMenu span.CLOSE{ 
    background-image: url(expand.gif);
    cursor:pointer;
    }
    -->
        </style>
    </head>
    <body>
    <div id="leftnav">            
        <div id="leftNavMenu">
            <ul class="tree dhtml">
                <li><a href="#" >Cheerleading Uniforms</a>
                <ul>
                    <li><a href="#" >Double-Knit Cheer Uniforms</a></li>
                    <li><a href="#" >Nylon Strech Cheerleader Uniforms</a></li>
                    <li><a href="#" >Uniform Packages</a></li>
                 </ul></li>
                <li class="selected"><a href="#" >Pom Poms</a>
                <ul>
                    <li><a href="#" >In-Stock Cheer Poms</a>
                    <ul>
                        <li><a href="#" >Holographic Poms</a></li>
                        <li><a href="#" >Metallic Poms</a></li>
                        <li><a href="#" >Plastic Poms</a></li>
                        <li><a href="#" >Youth Poms</a></li>  
                       </ul></li>
                    <li><a href="#" >Custom Cheerleading Poms</a>
                    <ul>
                        <li><a href="#" >Youth Poms</a></li>
                        <li><a href="#" >Flash Poms</a></li>
                        <li><a href="#" >Holographic Poms</a></li>
                        <li><a href="#" >Metallic Poms</a></li>
                        <li><a href="#" >Plastic Poms</a></li>
                        <li><a href="#" >Wetlook Poms</a></li>  
                    </ul></li>
                 </ul></li>
                <li><a href="#" >Cheerleading Shoes</a>
                <ul>
                    <li><a href="#" >Asics Shoes</a></li>
                    <li><a href="#" >Adidas Shoes</a></li>
                    <li><a href="#" >Chasse Shoes</a></li>
                    <li><a href="#" >Converse Shoes</a></li>
                    <li><a href="#" >Kaepa Shoes</a></li>
                    <li><a href="#" >Nike shoes</a></li>
                    <li><a href="#" >Power Shoes</a></li>
                    <li><a href="#" >Reebok Shoes</a></li>
                 </ul></li>
                <li><a href="#" >Cheer Skirts</a></li>
            </ul>    
        </div>            
    </div>
    </body>
    </html>
    Here's the Javascript for leftNavMenu.js:
    Code JavaScript:
    function autoUrl(name, dest) {
     
    var loc;
    var id_list;
     
    id_list = document.getElementById(name);
    loc = id_list.options[id_list.selectedIndex].value;
    if (loc != 0)
    location.href = dest+loc;
    return ;
    }
     
    /*
    ** show or hide element e depending on condition show
    */
    function toggle(e, show)
    {
    e.style.display = show ? '' : 'none';
    }
     
    function toggleMultiple(tab)
    {
    var len = tab.length;
     
    for (var i = 0; i < len; i++)
    if (tab[i].style)
    toggle(tab[i], tab[i].style.display == 'none');
    }
     
    /**
    * Show dynamicaly an element by changing the sytle "display" property
    * depending on the option selected in a select.
    *
    * @param string $select_id id of the select who controls the display
    * @param string $elem_id prefix id of the elements controlled by the select
    * the real id must be : 'elem_id'+nb with nb the corresponding number in the
    * select (starting with 0).
    */
    function showElemFromSelect(select_id, elem_id)
    {
    var select = document.getElementById(select_id);
    for (var i = 0; i < select.length; ++i)
    {
    var elem = document.getElementById(elem_id + select.options[i].value);
    if (elem != null)
    toggle(elem, i == select.selectedIndex);
    }
    }
     
    /**
    * Get all div with specified name and for each one (by id), toggle their visibility
    */
    function openCloseAllDiv(name, option)
    {
    var tab = $('*[name='+name+']');
    for (var i = 0; i < tab.length; ++i)
    toggle(tab[i], option);
    }
     
    /**
    * Toggle the value of the element id_button between text1 and text2
    */
    function toggleElemValue(id_button, text1, text2)
    {
    var obj = document.getElementById(id_button);
    if (obj)
    obj.value = ((!obj.value || obj.value == text2) ? text1 : text2);
    }
     
    function addBookmark(url, title)
    {
    if (window.sidebar)
    return window.sidebar.addPanel(title, url, "");
    else if ( window.external )
    return window.external.AddFavorite( url, title);
    else if (window.opera && window.print)
    return true;
    return true;
    }
     
    function writeBookmarkLink(url, title, text, img)
    {
    var insert = '';
    if (img)
    insert = writeBookmarkLinkObject(url, title, '<img src="' + img + '" alt="' + escape(text) + '" title="' + escape(text) + '" />') + '&nbsp';
    insert += writeBookmarkLinkObject(url, title, text);
    document.write(insert);
    }
     
    function writeBookmarkLinkObject(url, title, insert)
    {
    if (window.sidebar || window.external)
    return ('<a href="javascript:addBookmark(\'' + escape(url) + '\', \'' + escape(title) + '\')">' + insert + '</a>');
    else if (window.opera && window.print)
    return ('<a rel="sidebar" href="' + escape(url) + '" title="' + escape(title) + '">' + insert + '</a>');
    return ('');
    }
    //animate the opening of the branch (span.grower jQueryElement)
    function openBranch(jQueryElement, noAnimation) {
    jQueryElement.addClass('OPEN').removeClass('CLOSE');
    if(noAnimation)
    jQueryElement.parent().find('ul:first').show();
    else
    jQueryElement.parent().find('ul:first').slideDown();
    }
    //animate the closing of the branch (span.grower jQueryElement)
    function closeBranch(jQueryElement, noAnimation) {
    jQueryElement.addClass('CLOSE').removeClass('OPEN');
    if(noAnimation)
    jQueryElement.parent().find('ul:first').hide();
    else
    jQueryElement.parent().find('ul:first').slideUp();
    }
    //animate the closing or opening of the branch (ul jQueryElement)
    function toggleBranch(jQueryElement, noAnimation) {
    if(jQueryElement.hasClass('OPEN'))
    closeBranch(jQueryElement, noAnimation);
    else
    openBranch(jQueryElement, noAnimation);
    }
    //when the page is loaded...
    $(document).ready(function () {
    //to do not execute this script as much as it's called...
    if(!$('ul.tree.dhtml').hasClass('dynamized'))
    {
    //add growers to each ul.tree elements
    $('ul.tree.dhtml ul').prev().before("<span class='grower OPEN'> </span>");
     
    //dynamically add the '.last' class on each last item of a branch
    $('ul.tree.dhtml ul li:last-child, ul.tree.dhtml li:last-child').addClass('last');
     
    //collapse every expanded branch
    $('ul.tree.dhtml span.grower.OPEN').addClass('CLOSE').removeClass('OPEN').parent().find('ul:first').hide();
    $('ul.tree.dhtml').show();
     
    //open the tree for the selected branch
    $('ul.tree.dhtml .selected').parents().each( function() {
    if ($(this).is('ul'))
    toggleBranch($(this).prev().prev(), true);
    });
    toggleBranch( $('ul.tree.dhtml .selected').prev(), true);
     
    //add a fonction on clicks on growers
    $('ul.tree.dhtml span.grower').click(function(){
    toggleBranch($(this));
    });
    //mark this 'ul.tree' elements as already 'dynamized'
    $('ul.tree.dhtml').addClass('dynamized');
    }
    });

    Again thanks for your time any help you can give.

    -- Sandra

  2. #2
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,527
    Mentioned
    84 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by CyberFuture View Post
    I have a sample page setup where pom poms have been selected (li contains class=selected), but it's cheerleading uniforms thats opened up.
    I have a slightly different experience from the above explaination.

    What I experience is that clicking on any of the top-level categories result in no scripted behaviour at all, which is why the existing category for cheerleading remains open.

    The arrows are a span called "grower" so the link would want a similar event attached to it as well.

    Adding an event to the links so that they trigger the grower, appears to be a viable solution.

    Code javascript:
    $('ul.tree.dhtml a').click(function () { $(this).prev().click() });
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  3. #3
    SitePoint Evangelist CyberFuture's Avatar
    Join Date
    May 2001
    Location
    San Diego, CA
    Posts
    434
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hi Paul,
    Thank you for your reply. Sorry for the lateness of mine, but I had to go out of town unexpectedly and came back to find I had bigger dragons to slay.

    I think I need to explain things a little better. The sample page is a static page that is set-up as if it were the Pom Pom category page. The behavior I'm looking for is this: If you were on the site and clicked on Pom Poms category (or any other category with sub-category), you would be taken to the pom pom page and the nav would opens the category to reveal the sub-categories.

    The problem is that its not opening the category you click on, but the first category in the nav. This is why when you go to the sample page the Cheerleading Uniforms category is opened even though you are on the Pom Pom page and it's the pom pom's li with the selected class.

    With the correct Javascript fix, you should be able to reload the sample page and instead of the Cheerleading Uniform category being open, the Pom Pom category will be opened.

    Paul, I think you are on the right track. You fix opens the category on click, but on the actually test site, when you click on a category, you are then taken to that page and that takes us back to square 1. If a top level category has the class "selected", then it needs to open when the page is loaded. This isn't a problem with any of the sub-categories, they work fine when the they have the selected class.

    Thanks you for your help and I hope you will continue to do so.

    -- Sandra

  4. #4
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,527
    Mentioned
    84 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by CyberFuture View Post
    With the correct Javascript fix, you should be able to reload the sample page and instead of the Cheerleading Uniform category being open, the Pom Pom category will be opened.
    The scripted solution to your problem depends on how the navigation is handled. I see that you currently place an explicit class on the navigation, which implies to me that you have a large numbers of copies of the navigation spread around.

    There is a standard solution that means you only need to one version of the navigation, which involves placing an id attribute on the body tag:

    [highlight="html4strict"]
    <body id="pompoms">
    </highlight]

    and an id attribute on each of the top-level selections

    Code html4strict:
    <li id="nav-pompoms" class="selected"><a href="#">Pom Poms</a>

    Scripting can then use the value of the body tag to determine which of the navigation items to leave open.

    Here's a tutorial that takes you through the process.
    ID Your Body For Greater CSS Control and Specificity and a video tutorial of Current Nav Highlighting: Using PHP to Set the Body ID

    If you're willing to follow such a path, it makes the scripting easier as well. Let me know either way though, and we'll see what we can do.

    Oh, and you may want to get that test page of yours back up online too.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  5. #5
    SitePoint Evangelist CyberFuture's Avatar
    Join Date
    May 2001
    Location
    San Diego, CA
    Posts
    434
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hi Paul,

    It looks like I mistyped the sample page: http://www.omnicheer.com/test/index.html

    The actual website is dynamic. The script that builds the navigation, automatically inserts the selected class into the correct list item. I don't need to add an id to the body and li and do a comparison. All I need to do is have a bit of Javascript to find the li with the selected class and open it.

    Unfortunately, I'm coming to the conclusion the my Javascript skills are in serious needs of updating. Everything I try either causes everything to open up or has no effect at all.

    Thanks again for your continued help. The CSS trick is very neat.

    -- Sandra

  6. #6
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,527
    Mentioned
    84 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by CyberFuture View Post
    It looks like I mistyped the sample page: http://www.omnicheer.com/test/index.html
    Thanks.

    Quote Originally Posted by CyberFuture View Post
    Everything I try either causes everything to open up or has no effect at all.
    This here is how you would trigger the appropriately selected branch.

    Code javascript:
    $('ul.tree.dhtml li.selected span').click();

    Each click of that span toggles whether that particular section is open or closed.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  7. #7
    SitePoint Evangelist CyberFuture's Avatar
    Join Date
    May 2001
    Location
    San Diego, CA
    Posts
    434
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hi Paul,

    I need the list item to open on page load, not click. Since the list item is a link, setting the action to click would have no effect since the page would be re-loaded and un-do the effect.

    Thanks for your continued help.

    -- Sandra

  8. #8
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,527
    Mentioned
    84 Post(s)
    Tagged
    4 Thread(s)
    The code from my previous post performs a click action on the appropriate section which has the intended desired end-result of showing that section. It is that code which you would add to the jquery section of code that runs when the page is loaded.

    Please let me know if you require any further guidence with this.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript


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
  •