Creating Panel Menu with JQuery

Today, I am gonna show you how to create a very useful menu panel. Take a look at the demo of that first.

Well, this type of menu turns out to be very useful if you have a lot of links but you can’t show them in a drop down menu which may get very long. Other than that, it can also be used to allow quick form submissions or showing some piece of text. Basically, it is a div you can put just about anything in it. Let’s move on to creating this menu panel.

HTML

First of all, we create links which when hovered will show the associated panel.

  <div id="container">
    <ul id="menu">
      <li><a href="#" rel="panel_1">Link One</a></li>
      <li><a href="#" rel="panel_2">Link Two</a></li>
      <li><a href="#" rel="panel_3">Link Three</a></li>
    </ul>
  </div>

I will be using links’ rel attribute to refer to corresponding div element which is actually our panel element. Here is the html markup for our panel:

<div id="panel_1">
    <div class="left">
        <!-- The content for this panel goes here -->
    </div>
</div>

As can be seen, this panel has id panel_1 which is the same as rel value of the link shown above. That is how other two panels should be constructed.

CSS

First of all, we make sure that our menu is centered on the screen, so this is how we center the container div:

#container
{
  margin:0px auto;
  width:350px;
}

We make sure that there are no bullets there on the lists:

ul#menu
{
  list-style:none;
}

By default, list items are placed vertically because they are block-level elements, so we make them inline using this CSS so that they appear side by side with one pixel gap:

ul#menu li
{
  display:inline;
  background:#0099CC;
  float:left;
  margin-right:1px;
}

Then we make menu links as block-level elements because only after that we will be able to apply a width to them:

ul#menu li a
{
  color:#ffffff;
  font-weight:bold;
  text-decoration:none;
  display:block;
  width:100px;
  text-align:center;
  padding:5px;
}

Here is the CSS for any panel containing text. We will need to apply class text to any panel containing only text.

.text
{
  width:300px;
  text-align:justify;
  background:#333333;
  color:#CCCCCC;
  padding:15px;
}

Here is the CSS for any other panel:

div.left
{
  width:130px;
}

div.left ul
{
  list-style:none;
  margin-left:0px;
  padding:15px;
  background:#333333;
  color:#FFFFFF;
}

So for panels containing text, we will be using class text and for rest of the panels we will be using class left.

JQuery

First of all we create a global variable which will be equalized to opened panel later, so that we could use that variable later to operate on that opened panel like closing it.

<script type="text/javascript">

  var opened_one = null;

</script>

Now as mostly what we do, we use JQuery’s ready method to run our code. Our code will be run as soon as DOM becomes ready:

<script type="text/javascript">

  var opened_one = null;

  $(function(){
    // code here
  }

</script>

First of all we hide all panels using hide() method:

  // hide all panels first
  $('div[id*="panel"]').hide();

What it means is that hide all divs that have text panel anywhere in their id values. The *= means find given text anywhere in the provided attribute value.

To be able to actully position the panels right after the hovered links, we need to make them absolute positioned (I assume you have good understanding of CSS):

  // make the panels absolute positioned
  $('div[id*="panel"]').css('position', 'absolute');

Now we write the code for menu links which will be run when they are hovered upon using hover event:

  $('#menu a').hover(function(){
    // code here
  });

First we hide if there is a panel already open and get hovered link’s rel attribute value and store that in variable link_rel. We can get the attribute value using attr() method.

	// hide previously opened panel
	$(opened_one).hide();

	var link_rel = $(this).attr('rel');

Now we get the position of the hovered link (menu item) using offset() method and use that information to position the panels right after them using css() method of JQuery:

    //get the position of the hovered element
    var pos = $(this).offset();

   // get the panel near by hovered element now
    $('div#' + link_rel).css({
      'left': pos.left + 'px',
      'top': (pos.top + $(this).height() + 10) + 'px',
      'zIndex': '5000'
    });

As can be seen, we set the top of panel equal to that of hovered link plus its height plus 10 which we need because we have assigned in CSS with 5 pixels of padding. As per CSS box model, we need to calculate paddings for two sides thus equaling to 10. We also set the z-index of current panel to a larger value so that it appears over any other opened panel although possibility of this is less but we still want to make sure that it makes sense.

Then we show the corresponding panel using fadeIn() animation and once that it is opened/shown, we set the variable opened_one to this panel so that we could hide it later if another panel is to be opened.

    // finaly show the relevant hidden panel
    $('div#' + link_rel).fadeIn('slow');

   // this is currently opened
   opened_one = $('div#' + link_rel);

We want to hide the panel if the mouse moves away from its area using fadeOut():

    // hide it back when mouse arrow moves away
    $('div#' + link_rel).hover(function(){}, function(){
		$(this).fadeOut('slow');
    });

That’s all there is to it. Of couse explaining it takes more time and a lot of theory but if you think about it and practice, it should not be that hard to create this very useful menu panel using JQuery.

Download Code.

About these ads

13 thoughts on “Creating Panel Menu with JQuery

  1. Thanks. Great tutorial. This actually helped me implement panel menus for my project.
    One problem though and I can see that on your demo site as well
    If I hover over any of the menu links,panel opens up. Now instead of moving our house to opened menu, move mouse away from the panel and menu option(top,right,left) without hovering over any other menu option. The opened panel stays on the page.Is there a way to avoid this?

    thanks

    • Thanks for liking it :)

      I could not understand what you are talking about. Could you elaborate a little more. Thanks

  2. sorry, should have been clearer. There are 2 issues. Let me see If I can describe it better this time.
    In your demo, there are three links ‘Link1′,’Link2′ and ‘Link3′. Hover over any of these links,the panel will open it. This works great.

    1) Now 2nd attempt, hover over ‘Link1′ but don’t take your mouse cursor over the panel or to the right(over link2 or link3) instead hover away to the top or to the left. You will notice that panel stays open. Here is screen shot of what I meant:

    2) This one is hard to produce but happens a lot. Sometimes more than one panel stay open. Here is a SS to describe this : http://imgur.com/vf4pz.png

    Hope this is clear.
    Thanks

  3. You can avoid that by simply putting this line at the end of the ready handler:

    $(‘body’).hover(function(){}, function(){$(‘div[id*="panel"]‘).hide();})

  4. Very nice little menu :)

    Curious – what would one need to add to the code to keep a hover state on a menu item when the cursor has moved off it on to the active panel?

    Thx

  5. If there is a DIV just above the menu links, the $(‘body’).hover(function(){}, function(){$(‘div[id*="panel"]‘).hide();}) still leaves the panel open when mousing out from the top? Have you encountered this problem. Strangely if the element immediately above is it works fine.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s