123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- /**
- * Generic menu drilldown plugin for standard Drupal menu tree markup.
- * The plugin should be inited against a DOM element that *contains*
- * a Drupal ul.menu tree. Example:
- *
- * $('div.block-menu').drilldown('init', params);
- *
- * You must provide the following parameters as settings:
- *
- * var params = {
- * activePath : A drupal menu path that is currently active including the basePath e.g. "/mysite/node"
- * trail : A jquery selector to the DOM element that should act as the trail container, e.g. "div.my-menu-breadcrumb-trail"
- * rootTitle : The title to use for the root menu item if the menu does not already possess one. Optional.
- * }
- *
- */
- (function($) {
- $.fn.drilldown = function(method, settings) {
- var menu = this;
- var activePath;
- var rootTitle = settings.rootTitle || 'Home';
- switch (method) {
- case 'goTo':
- // If the passed link refers to the current page, don't follow through
- // the link.
- if (this.activePath && this.activePath === $(settings.activeLink).attr('href')) {
- return false;
- }
- return true;
- case 'setActive':
- var breadcrumb = [];
- var activeMenu;
- $(settings.activeLink).each(function() {
- // Traverse backwards through menu parents and build breadcrumb array.
- $(this).parents('ul.menu').each(function() {
- if ($(this).parents('ul.menu').size() > 0) {
- $(this).siblings('a').each(function() {
- breadcrumb.unshift($(this));
- });
- }
- // If this is a root menu with no root link to accompany it,
- // generate one such that the breadcrumb may reference it.
- else if ($(this).children('li').size() > 1) {
- var root;
- if ($(this).siblings('a.drilldown-root').size() > 0) {
- root = $(this).siblings('a.drilldown-root');
- }
- else {
- root = $('<a href="#" class="drilldown-root" style="display:none">'+rootTitle+'</a>');
- $(this).before(root);
- }
- breadcrumb.unshift(root);
- }
- });
- // If we have a child menu (actually a sibling in the DOM), use it
- // as the active menu. Otherwise treat our direct parent as the
- // active menu.
- if ($(this).next().is('ul.menu')) {
- activeMenu = $(this).next();
- breadcrumb.push($(this));
- }
- else {
- activeMenu = $(this).parents('ul.menu').eq(0);
- }
- if (activeMenu) {
- $('.drilldown-active-trail', menu).removeClass('drilldown-active-trail');
- $('ul.menu', menu).removeClass('drilldown-active-menu').removeClass('clearfix');
- $(activeMenu)
- .addClass('drilldown-active-menu').addClass('clearfix')
- .parents('li').addClass('drilldown-active-trail').show();
- }
- });
- // Render the breadcrumb to the target DOM object
- if (breadcrumb.length > 0) {
- var trail = $(settings.trail);
- trail.empty();
- for (var key in breadcrumb) {
- if (breadcrumb[key]) {
- // We don't use the $().clone() method here because of an
- // IE & jQuery 1.2 bug.
- var clone = $('<a></a>')
- .attr('href', $(breadcrumb[key]).attr('href'))
- .attr('class', $(breadcrumb[key]).attr('class'))
- .html($(breadcrumb[key]).html())
- .addClass('depth-'+key)
- .appendTo(trail);
- // We add a reference to the original link and a click handler
- // that traces back to that instance to set as the active link.
- $('a.depth-'+key, trail)
- .data('original', $(breadcrumb[key]))
- .click(function() {
- settings.activeLink = $(this).data('original');
- // If the clicked link does not reference the current
- // active menu, set it to be active.
- if (settings.activeLink.siblings('ul.drilldown-active-menu').size() === 0) {
- menu.drilldown('setActive', settings);
- return false;
- }
- // Otherwise, pass-through and allow the link to be clicked.
- return menu.drilldown('goTo', settings);
- });
- }
- }
- }
- // Event in case others need to update themselves when a new active
- // link is set.
- $(menu).trigger('refresh.drilldown');
- break;
- case 'init':
- if ($('ul.menu ul.menu', menu).size() > 0) {
- $(menu).addClass('drilldown');
- $(settings.trail).addClass('drilldown-trail');
- // Set initial active menu state.
- var activeLink;
- $('ul.menu a', menu).removeClass('active');
- if (settings.activePath && $('ul.menu a[href="'+settings.activePath+'"]', menu).size() > 0) {
- this.activePath = settings.activePath;
- activeLink = $('ul.menu a[href="'+settings.activePath+'"]', menu).addClass('active');
- }
- if (!activeLink) {
- activeLink = $('ul.menu a.active', menu).size() ? $('ul.menu a.active', menu) : $('ul.menu > li > a', menu);
- }
- if (activeLink) {
- menu.drilldown('setActive', {
- activeLink: $(activeLink[0]),
- trail: settings.trail,
- rootTitle: rootTitle
- });
- }
- // Attach click handlers to menu items
- $('ul.menu li:has(ul.menu)', this).click(function() {
- if ($(this).parent().is('.drilldown-active-menu')) {
- if (menu.data('disableMenu')) {
- return true;
- }
- else {
- var url = $(this).children('a').attr('href');
- var activeLink = $('ul.menu a[href="'+url+'"]', menu);
- menu.drilldown('setActive', {
- activeLink: activeLink,
- trail: settings.trail,
- rootTitle: rootTitle
- });
- return false;
- }
- }
- });
- $('ul.menu li:has(ul.menu) a', menu).click(function() {
- menu.data('disableMenu', true);
- });
- }
- break;
- }
- return this;
- };
- })(jQuery);
|