jQuery Dropdown Panels
A couple of recent projects have needed a means of displaying dropdown panels that could serve as menus, forms and lists. To remind myself how to build the interface, I’m going to document the jQuery code that makes it all work.
HTML
The code applies the same class name to each nav-item
where each has a child with a class of panel
. The panel
class can be a ul
element or a form
element or a div
or any block-level element.
<nav role="navigation" class="main-nav">
<ul class="menu">
<li id="nav-about" class="nav-item">
<a href="#" id="menu-item">Menu</a>
<ul class="panel">
<li><a href="#">Item 1</a></li>
<li><a href="#">Item 2</a></li>
<li><a href="#">Item 3</a></li>
<li><a href="#">Item 4</a></li>
<li><a href="#">Item 5</a></li>
</ul>
</li>
<li id="utility-nav">
<ul>
<li id="nav-search" class="nav-item">
<a href="#">Search</a>
<form class="panel form-fields" id="form-search">
<fieldset class="fields-search">
<input type="text" id="search-terms" placeholder="Enter keywords..." />
<input type="submit" value="Search" class="submit-search" />
</fieldset>
</form>
</li>
<li id="nav-directory" class="nav-item">
<a href="#" id="nav-directory-item"><b>A-Z</b> Directory</a>
<div class="panel" id="panel-directory">
<p>Find resources alphabetically</p>
<ul id="alpha">
<li><a href="#a" rel="A">A</a></li>
<li><a href="#b" rel="B">B</a></li>
<li><a href="#c" rel="C">C</a></li>
<li><a href="#d" rel="D">D</a></li>
<li><a href="#e" rel="E">E</a></li>
<li><a href="#f" rel="F">F</a></li>
<li><a href="#g" rel="G">G</a></li>
<li><a href="#h" rel="H">H</a></li>
<li><a href="#i" rel="I">I</a></li>
<li><a href="#j" rel="J">J</a></li>
<li><a href="#k" rel="K">K</a></li>
<li><a href="#l" rel="L">L</a></li>
<li><a href="#m" rel="M">M</a></li>
<li><a href="#n" rel="N">N</a></li>
<li><a href="#o" rel="O">O</a></li>
<li><a href="#p" rel="P">P</a></li>
<li><a href="#q" rel="Q">Q</a></li>
<li><a href="#r" rel="R">R</a></li>
<li><a href="#s" rel="S">S</a></li>
<li><a href="#t" rel="T">T</a></li>
<li><a href="#u" rel="U">U</a></li>
<li><a href="#v" rel="V">V</a></li>
<li><a href="#w" rel="W">W</a></li>
<li><a href="#x" rel="X">X</a></li>
<li><a href="#y" rel="Y">Y</a></li>
<li><a href="#z" rel="Z">Z</a></li>
<li><a href="##" rel="#">#</a></li>
</ul>
</div>
</li>
<li id="nav-contact"><a href="#">Contact</a></li>
</ul>
</li>
</ul>
</nav>
JavaScript
The jQuery code checks that the document is loaded. Then, on a click event on a navigation item, a jQuery selector finds each nav-item
and first removes the open
class from all nav-item
elements except for the item that triggered the onclick
event. This item can then be toggled open and closed. A click event is added to the html
element to add a “click outside” event to close all panels when the mouse clicks on anything other than a nav-item
. But the “click outside” event will close the panels when the items are clicked. So, the stopPropagation
method is added to the click event for the panel
class.
$(document).ready(function(){
// Display global navigation panels on click
$('.nav-item').click(function(event){
event.stopPropagation(); // Stop propagation of the click outside event
$('.open').not($(this)).removeClass("open");
$(this).toggleClass("open");
});
// Hide search menu panels when clicking outside
$("html").click(function() {
$(".open").removeClass("open");
});
// Keep panels open when clicked
$(".panel").click(function(event){
event.stopPropagation();
});
});
CSS
The styles for the panels allow for a fallback to display the panels on hover when JavaScript is not running, as Modernizr is being used to test that availability of JavaScript. Otherwise, the open
class will be used to toggle the display of the dropdown panel.
.nav-item .panel {
display: none;
position: absolute;
left: 0;
right: 0;
z-index: 20;
width: auto;
}
.no-js .nav-item:hover .panel,
.nav-item.open .panel {
display: block;
}
Comments for this article
No comments have been made so far.