views:

201

answers:

1

Here's my code: UPDATED JS

jQuery(document).ready(function()
{
   var cookieName = 'activeMenus';
   var openMenus  = (jQuery.cookie(cookieName) == null) ? 0 : jQuery.cookie(cookieName).substring(1).split(',');
   var wookie     = '';

   jQuery('ul.menu li ul').css('display', 'none');

   // Reopen all the menus from the cookie
   if (openMenus != 0)
   {
      for (var i = 0; i < openMenus.length; i++)
      {
         alert('Opening: ' + openMenus[i]);
         jQuery('ul.menu li').children('ul').eq(openMenus[i]).css('display', 'block');
      }
   }

   // Hide the menu upon click and modify the cookie
   jQuery('ul.menu span.topdaddy span').click(function()
   {
      // Toggle the menu for the clicked link
      jQuery(this).parents('li').find('ul').slideToggle('slow', function()
      {
         // Once the menu has been toggled - Find all the open menus
         jQuery('ul.menu li').children('ul:visible').each(function()
         {
            wookie += ',' + jQuery(this).index(); // Build the index list
            jQuery.cookie(cookieName, wookie);
         });
      });

      wookie = '';
  });
});

HTML

<ul class="menu">
   <li class="item1">
      <a href="#"><span>Link 1</span></a>
   </li>

   <li class="parent item55">
      <span class="topdaddy"><span>Link 2</span></span>

      <ul>
         <li class="item62">
            <a href="#"><span>Link 3</span></a>
         </li>

         <li class="item63">
            <a href="#"><span>Link 4</span></a>
         </li>
      </ul>
   </li>

   <li class="parent item56">
      <span class="topdaddy"><span>Link 5</span></span>

      <ul>
         <li class="item69">
            <a href="#"><span>Link 6</span></a>
         </li>

         <li class="parent item70">
            <ul>
               <li>asdasd</li>
            </ul>
         </li>
      </ul>
   </li
</ul>

It's a menu system that uses cookies to remembers the currently opened menus to reopen those menus each page load.

The code works... But it's a little buggy.

The .eq() call is opening index 2 rather than 1. They're both supposed to be 0-based indexes, so I see no reason why it should be doing this.

Any ideas?

+1  A: 

Ok. I added > where it was needed. Also, the index() number we were grabbing took into account the first li under ul.menu that doesn't have .parent class. That's fine, but I just had to make sure that we setting the index on the full set of li under ul.menu, not limiting the collection to li.parent

Let me know how this works for you.

    $(document).ready(function() {

           var cookieName = 'activeMenus';
           var openMenus  = (jQuery.cookie(cookieName) == null) ? 0 : jQuery.cookie(cookieName).substring(1).split(',');
           var wookie     = '';

           jQuery('ul.menu > li.parent > ul').css('display', 'none');

           if (openMenus != 0) {
              for (var i = 0; i < openMenus.length; i++) {
                 alert('Opening: ' + openMenus[i]);
                jQuery('ul.menu > li').eq(openMenus[i]).children('ul').css('display', 'block');
              }
           }
           jQuery('ul.menu span.topdaddy').click(function() {
              jQuery(this).next().slideToggle('slow', function() {
                 jQuery('ul.menu > li.parent > ul:visible').each(function() {
                    wookie += ',' + jQuery(this).parent().index(); 
                    jQuery.cookie(cookieName, wookie);
                 });
              });
              wookie = '';
          });
    });

This code:

jQuery('ul.menu li').children('ul:visible').each(function()
     {
        wookie += ',' + jQuery(this).parent().index(); // Build the index list
        jQuery.cookie(cookieName, wookie);
     });

...seems to be getting the index of a li element that is a child of ul.menu.

While this code:

     jQuery('ul.menu li ul').eq(openMenus[i]).css('display', 'block');

...seems to be using the index from above, but on a different set of elements (the ul that is a child of the index you stored in the cookie).

So it looks like you're taking the index of a ul.menu li and using it on a ul.menu li ul.

patrick dw
The first code block should be getting the index of the first child UL's of each `ul.menu li`, no? How would I match up those two code blocks to reference the same UL? :/
Gary
It would be, except that this line `wookie += ',' + jQuery(this).parent().index();` is grabbing the index of the **parent** of the visible `ul` (which is the `li`). Get rid of `parent()`, and you will be getting the index of the `ul` itself.
patrick dw
Wasn't expecting a reply that quick... Cheers :> I removed parent() so it's just pulling jQuery(this).index() but it's still opening the wrong menu item.
Gary
It seems removing parent() is causing index() to return '1' :/
Gary
Please edit your question with a portion of your HTML. Also update any changes you've made to js. I'm trying to figure out what's going on in your code, but I'm not quite getting it.
patrick dw
Updated my question
Gary
Just to keep you updated, I think I see the problem. The ul.menu structure goes as deep as `ul.menu li ul li ul`. What I'm trying to do is open `ul.menu li ul`. The block of code that gets the index and saves it in the cookie works perfectly. The block of code that opens the menu based on the index is what's flawed. I've noticed that it's opening up `ul.menu li ul li ul`. It's going too deep. I'm guessing this is causing the index problem.
Gary
Direct descendant child selectors to the rescue! ul.menu > li > ul
D_N
Yeah, if it goes deeper than the code you posted, that could be an issue. In terms of `index()` returning '1', that's because the element is at index 1. `index()` returns its position relative to its siblings. The element `span.topdaddy` is at index 0.
patrick dw
Made a bunch of edits to my answer. Things can be simplified quite a bit. I think I've provided a start.
patrick dw
The reason for me using `jQuery('ul.menu li').children('ul:visible').each(function()` is that it stops me from having to remove indexes from the 'wookie' when menus get closed. When each menu is clicked it does a quick look to see what menus are open and regenerates the wookie. My code to open the menus is now `jQuery('ul.menu li').eq(openMenus[i]).find('ul').css('display', 'block');` which seems to work. The problem I'm having is finding which menus are open. It, now seems to go deeper than I want. I'm playing around with `jQuery('ul.menu > li > ul:visible').each(function()` which is failing.
Gary
It's still not working >.< A few things 1) I messed up my HTML a little which is now fixed in my original post. There's an extra `ul li` combination. 2) The `>` selector doesn't seem to be working as it should. `jQuery('ul.menu li.parent > ul').css('display', 'none');` is causing all UL's to be set to `display: none` instead of just the first child. 3) What's currently happening when I run the code is my alert() is firing off 17 alerts counting between 0 and 4 for the specific LI I click.
Gary
Yeah, now that you have nested elements with li.parent, you'll need: `jQuery('ul.menu > li.parent > ul').css('display', 'none');` Notice the extra `>`. This will limit it to immediate children of `ul.menu`. Do the same inside the click() event. I'll update my answer in a minute.
patrick dw
Ok, I updated my answer. Give it a try. Also (somewhat off topic), I noticed that you seem to have a unique class for each `li`. That's fine, but if those are unique, it would seem that you would want those to be IDs instead of classes. Just a thought.
patrick dw