Improved jQuery MobileMenu Function

There is a function called jQuery Mobile Menu that turns an unordered list menu into a dropdown select menu (which you can use in responsive web designs as a navigation control). But can it handle multiple menus?

If you take a look at the code you call the function like this:

jQuery('#menu-top-menu').mobileMenu();

The output turns something like this:

<ul class="drop-menu" id="menu-top-menu">
<li class="menu-item"><a href="http://localhost/">Home</a></li>
...

and appends a new control after the above and looks like this:

<select class="select-menu">
<option value="#">Navigate to...</option>
<option value="http://localhost/" selected="selected"> Home</option>
...

By default the .mobileMenu() function sets the class name as ‘select-menu‘. But what happens if you have multiple menus – like a menu for the top and bottom of your web page? If you make two (or more) .mobileMenu() calls it would just append menu items to all .select-menu objects – so in the end you will end up with all your dropdown menus having duplicate items – get me?

So the work-around – modifications to the function to change the class into an id:

(function($){
$.fn.mobileMenu = function(selectID) { // renamed options to selectID for simplicity
var defaults = {
defaultText: 'Navigate to...',
className: 'select-menu',
subMenuClass: 'sub-menu',
subMenuDash: '&ndash;'
},
settings = $.extend( defaults, selectID ), // renamed here
el = $(this);
this.each(function(){
// ad class to submenu list
el.find('ul').addClass(settings.subMenuClass);
// Create base menu
$('&lt;select /&gt;',{
'id' : selectID, // this will be our unique identifier
'class' : settings.className
}).insertAfter( el );
// Create default option
$('&lt;option /&gt;', {
"value" : '#',
"text" : settings.defaultText
}).appendTo( '#' + selectID ); // change to the id instead of class
// Create select option from menu
el.find('a').each(function(){
var $this = $(this),
optText = '&nbsp;' + $this.text(),
optSub = $this.parents( '.' + settings.subMenuClass ),
len = optSub.length,
dash;
// if menu has sub menu
if( $this.parents('ul').hasClass( settings.subMenuClass ) ) {
dash = Array( len+1 ).join( settings.subMenuDash );
optText = dash + optText;
}
// Now build menu and append it
$('&lt;option /&gt;', {
"value" : this.href,
"html" : optText,
"selected" : (this.href == window.location.href)
}).appendTo( '#' + selectID ); // change to the id instead of class
}); // End el.find('a').each
// Change event on select element
$('#' + selectID).change(function(){ // monitor id changes instead of class
var locations = $(this).val();
if( locations !== '#' ) {
window.location.href = $(this).val();
};
});
}); // End this.each
return this;
};
})(jQuery);

There – now you can have multiple dropdown menus passing through different ids and have a unique dropdown menu for each:

jQuery('#menu-top-menu').mobileMenu('select-menu-top');
jQuery('#menu-bottom-menu').mobileMenu('select-menu-bottom');

Too easy!

Posted by Tom Storms  |  0 Comment  |  in Code Snippets

About Tom Storms

Founder of Express Developments, Web Developer, Software Programmer and Designer

Post a Comment

Your email address will not be published. Required fields are marked *

*

Copyright © 2015 - Express Developments