Wednesday, August 1, 2012

Creating Pop-Out Menus in SharePoint using jQuery/jQueryUI and CSS

Background
On our SharePoint based intranet home page, we have custom web parts along the right hand side of the screen. These web parts display various sets of links - creating a right hand navigation menu system. Two of these web parts displayed links from a SharePoint list behind the scenes. So the content was somewhat dynamic and could easily be maintained by adding or modifying list items; easy.
Problem
With so much functionality on the home page resulting in tons of web parts, we needed ways to slim down the processing. While we tweaked the list item access and various other things, these menu lists still needed to be lighter - like static HTML. In addition, since these links are used on an as-needed basis, they really don't need to be shown all of the time let alone cost any time to render.
 

Proposed Solution
The proposed solution was to combine the two sets of lists into one pop-out menu which would be lightweight.

Technical Solution
We wanted a section of the right hand navigation menus to show the heading but when hovered over (via the mouse), would pop-out and display two columns of lists. The HTML markup was easy but what about the hovering?

Enter CSS. We originally used various CSS classes and styles to control the size and display of the menu including the use of the :hover style. This worked great but there was no delay and as such, any mouse over would pop the menu up regardless if the user was intending to go to the new menu. So we needed a way to change the styles but use a delay.

Enter jQuery and jQueryUI. Through the use of jQuery as well as the jQuery UI Hover functionality, we were able to delay the pop-out as well as cancel the potential pop-out if the user happened to mouse over the menu to get somewhere else.


Result (sanitized versions)

Menu initial appearance:


Menu pop-out on hover:


Hint: See live demo in action at the bottom of this post!


Menu Markup
The menu HTML consists of one overall <div> (in our example named OnlineServices). Within that <div> is our main container (named OS-container) whose style changes based on the hovering. Within the container is a title div and a tip div. The title div is the initial state while the tip div is the pop-out menu markup.

Below is a shortened version of the markup:

<div id="OnlineServices">
 <div id="OS-container" class="OS-container-collapsed">
  <div class="OS-title">Online Services and Company Links</div>
  <div class="OS-tip">
   <div class="OS-tip-col">
    <strong class="OS-tip-col-title">Online Services</strong>
    <ul>
     <li>
     <a href="http://stevethemanmann.com" onfocus="OnLink(this)">
     Audio Conference Reservation</a></li>
    </ul>
   </div>
   <div class="OS-tip-col">
    <strong class="OS-tip-col-title">Company  Links</strong>
    <ul>
     <li>
     <a href="http://stevethemanmann.com" onfocus="OnLink(this)">
     Client Visit Feedback Form</a></li>
    </ul>
   </div>
  </div>
 </div>
</div>

CSS Styles
The main CSS styles are shown below. The important classes to note are the OS-container-collapsed and the OS-container-expanded. We also included a :hover for the collapsed to make the initial menu appear active (but this hover has nothing to do with the pop-out functionality).

#OnlineServices{position:relative; display:block; height:40px;margin:6px 0; z-index:100}
.OS-container-collapsed{height:38px; width:298px; overflow:hidden;  position: absolute; top:0; right:0; display: block; border: 1px #ccc solid;background-color:#eee; background-image:url(/_layouts/images/MNetImages/icon-expandmenu.png); background-position:255px 0px; background-repeat:no-repeat;}
.OS-container-collapsed:hover{background-color:#f8f8f8;}
.OS-container-expanded{ height:auto; width:620px; overflow:visible; position:absolute;  top:0; right:0; display: block; border: 1px #ccc solid;background-color:#eee; background-image:none; -moz-box-shadow: 0px 1px 2px #999;-webkit-box-shadow: 0px 1px 2px #999;box-shadow: 0px 1px 2px #999; float:right; }


jQuery
The key to the delayed popping out and not responding if the user just happened to graise the menu was in the jQuery:

 $(document).ready(function(){
     var timer;
        $('#OS-container').hover(
            function(){
             if(timer) {                        
               clearTimeout(timer);
               timer = null
               }
                timer = setTimeout(function(){
                    $('#OS-container').removeClass('OS-container-collapsed');
                    $('#OS-container').addClass('OS-container-expanded');
                }, 500);
            },
            function(){
             if(timer) {                        
               clearTimeout(timer);
               timer = null
               }
                $('#OS-container').removeClass('OS-container-expanded');
                $('#OS-container').addClass('OS-container-collapsed');
            });
    });

Essentially, on the hover, the CSS classes are swapped to perform an expand or collapse of the menu (creating the pop-out effect) but only if the mouse is hovering for more than 1/2 second (500ms).



LIVE DEMO: (hover over the Online Services and Company Links box)
















View the source of this post and check out the full jQuery code, styles, and markup! Look for "Online Services Menu".

5 comments:

  1. Thanks Roger! Hope it helps!

    I never claim that my code is right or wrong but when it works and solves a problem then I assume it is pretty close to being right.

    ReplyDelete
  2. Hey steve thanks for doing this, I did buy your book that covered this as well. For my company I ended up using a jquery slider and got the menu added to my top level navigation so I have a menu of non sharepoint links I can load through a central jquery script, so if we need to add more links then we edit one source and the master page on each site just pulls them in. Thanks for the inspiration and the code to get this started. It was well worth it.

    ReplyDelete
    Replies
    1. Perfect! I have been doing lots of client side scripting lately. It's fast and neat!! I want to write a SP.js book but I don't have time with school work.

      Delete
  3. God bless you sir. Honestly, God bless you. The lack of documentation for SP.js is mind boggling. You are a hero.

    ReplyDelete