Menu icon Foundation

My Posts

No Content

My Comments

Endre R. Fehn commented on Guy Van Bael's post about 3 years

A link for downloading my patched foundation.js and foundation.min.js:

https://www.dropbox.com/s/546737o4buzqp16/f_605_drilldown.zip?dl=0

I agree this was an unfortunate omission, but for me there are too many other good improvements to skip v. 6. This is one that will be included shortly I guess.

Endre R. Fehn commented on Guy Van Bael's post about 3 years

Here is the patched foundation.drilldown.js -- if you include foundation.js in you project, the same changes needs to be made in foundation.js (and foundation.min.js).

 /**
 * Drilldown module.
 * @module foundation.drilldown
 * @requires foundation.util.keyboard
 * @requires foundation.util.motion
 * @requires foundation.util.nest
 */
!function($, Foundation){
  'use strict';

  /**
   * Creates a new instance of a drilldown menu.
   * @class
   * @param {jQuery} element - jQuery object to make into an accordion menu.
   * @param {Object} options - Overrides to the default plugin settings.
   */
  function Drilldown(element, options){
    this.$element = element;
    this.options = $.extend({}, Drilldown.defaults, this.$element.data(), options);

    Foundation.Nest.Feather(this.$element, 'drilldown');

    this._init();

    Foundation.registerPlugin(this);
    Foundation.Keyboard.register('Drilldown', {
      'ENTER': 'open',
      'SPACE': 'open',
      'ARROW_RIGHT': 'next',
      'ARROW_UP': 'up',
      'ARROW_DOWN': 'down',
      'ARROW_LEFT': 'previous',
      'ESCAPE': 'close',
      'TAB': 'down',
      'SHIFT_TAB': 'up'
    });
  }
  Drilldown.defaults = {
    /**
     * Markup used for JS generated back button. Prepended to submenu lists and deleted on `destroy` method, 'js-drilldown-back' class required. Remove the backslash (`\`) if copy and pasting.
     * @option
     * @example '<\li><\a>Back<\/a><\/li>'
     */
    backButton: '<li class="js-drilldown-back"><a>Back</a></li>',
    /**
     * Markup used for JS generated parent button. Prepended to submenu lists and deleted on `destroy` method, 'js-drilldown-parent' class required. Remove the backslash (`\`) if copy and pasting.
     * @option
     * @example '<\li class="js-drilldown-parent"><\a href="#href">#txt<\/a><\/li>'
     */
    parentButton: '',
    /**
     * Markup used to wrap drilldown menu. Use a class name for independent styling; the JS applied class: `is-drilldown` is required. Remove the backslash (`\`) if copy and pasting.
     * @option
     * @example '<\div class="is-drilldown"><\/div>'
     */
    wrapper: '<div></div>',
    /**
     * Allow the menu to return to root list on body click.
     * @option
     * @example false
     */
    closeOnClick: false
    // holdOpen: false
  };
  /**
   * Initializes the drilldown by creating jQuery collections of elements
   * @private
   */
  Drilldown.prototype._init = function(){
    this.$submenuAnchors = this.$element.find('li.has-submenu');
    this.$submenus = this.$submenuAnchors.children('[data-submenu]');
    this.$menuItems = this.$element.find('li:visible').not('.js-drilldown-back').attr('role', 'menuitem');

    this._prepareMenu();

    this._keyboardEvents();
  };
  /**
   * prepares drilldown menu by setting attributes to links and elements
   * sets a min height to prevent content jumping
   * wraps the element if not already wrapped
   * @private
   * @function
   */
  Drilldown.prototype._prepareMenu = function(){
    var _this = this;
    // if(!this.options.holdOpen){
    //   this._menuLinkEvents();
    // }
    this.$submenuAnchors.each(function(){
      var $sub = $(this);
      var $link = $sub.find('a:first');
      $link.data('savedHref', $link.attr('href')).removeAttr('href');
      $sub.children('[data-submenu]')
          .attr({
            'aria-hidden': true,
            'tabindex': 0,
            'role': 'menu'
          });
      _this._events($sub);
    });
    this.$submenus.each(function(){
      var $menu = $(this),
          $back = $menu.find('.js-drilldown-back'),
          $parent = $menu.find('.js-drilldown-parent');
      if (!$parent.length){
        $menu.prepend(_this.options.parentButton
                      .replace(/#href/g,$menu.parent().find('a:first').data('savedHref'))
                      .replace(/#txt/g,$menu.parent().find('a:first').html()));
      }
      if(!$back.length){
        $menu.prepend(_this.options.backButton);
        _this._back($menu);
      }
    });
    if(!this.$element.parent().hasClass('is-drilldown')){
      this.$wrapper = $(this.options.wrapper).addClass('is-drilldown').css(this._getMaxDims());
      this.$element.wrap(this.$wrapper);
    }

  };
  /**
   * Adds event handlers to elements in the menu.
   * @function
   * @private
   * @param {jQuery} $elem - the current menu item to add handlers to.
   */
  Drilldown.prototype._events = function($elem){
    var _this = this;

    $elem.off('click.zf.drilldown')
    .on('click.zf.drilldown', function(e){
      if($(e.target).parentsUntil('ul', 'li').hasClass('is-drilldown-submenu-parent')){
        e.stopImmediatePropagation();
        e.preventDefault();
      }

      // if(e.target !== e.currentTarget.firstElementChild){
      //   return false;
      // }
      _this._show($elem);

      if(_this.options.closeOnClick){
        var $body = $('body').not(_this.$wrapper);
        $body.off('.zf.drilldown').on('click.zf.drilldown', function(e){
          e.preventDefault();
          _this._hideAll();
          $body.off('.zf.drilldown');
        });
      }
    });
  };
  /**
   * Adds keydown event listener to `li`'s in the menu.
   * @private
   */
  Drilldown.prototype._keyboardEvents = function() {
    var _this = this;
    this.$menuItems.add(this.$element.find('.js-drilldown-back')).on('keydown.zf.drilldown', function(e){
      var $element = $(this),
          $elements = $element.parent('ul').children('li'),
          $prevElement,
          $nextElement;

      $elements.each(function(i) {
        if ($(this).is($element)) {
          $prevElement = $elements.eq(Math.max(0, i-1));
          $nextElement = $elements.eq(Math.min(i+1, $elements.length-1));
          return;
        }
      });
      Foundation.Keyboard.handleKey(e, _this, {
        next: function() {
          if ($element.is(_this.$submenuAnchors)) {
            _this._show($element);
            $element.on(Foundation.transitionend($element), function(){
              $element.find('ul li').filter(_this.$menuItems).first().focus();
            });
          }
        },
        previous: function() {
          _this._hide($element.parent('ul'));
          $element.parent('ul').on(Foundation.transitionend($element), function(){
            setTimeout(function() {
              $element.parent('ul').parent('li').focus();
            }, 1);
          });
        },
        up: function() {
          $prevElement.focus();
        },
        down: function() {
          $nextElement.focus();
        },
        close: function() {
          _this._back();
          //_this.$menuItems.first().focus(); // focus to first element
        },
        open: function() {
          if (!$element.is(_this.$menuItems)) { // not menu item means back button
            _this._hide($element.parent('ul'));
            setTimeout(function(){$element.parent('ul').parent('li').focus();}, 1);
          } else if ($element.is(_this.$submenuAnchors)) {
            _this._show($element);
            setTimeout(function(){$element.find('ul li').filter(_this.$menuItems).first().focus();}, 1);
          }
        },
        handled: function() {
          e.preventDefault();
          e.stopImmediatePropagation();
        }
      });
    }); // end keyboardAccess
  };

  /**
   * Closes all open elements, and returns to root menu.
   * @function
   * @fires Drilldown#closed
   */
  Drilldown.prototype._hideAll = function(){
    var $elem = this.$element.find('.is-drilldown-sub.is-active').addClass('is-closing');
    $elem.one(Foundation.transitionend($elem), function(e){
      $elem.removeClass('is-active is-closing');
    });
        /**
         * Fires when the menu is fully closed.
         * @event Drilldown#closed
         */
    this.$element.trigger('closed.zf.drilldown');
  };
  /**
   * Adds event listener for each `back` button, and closes open menus.
   * @function
   * @fires Drilldown#back
   * @param {jQuery} $elem - the current sub-menu to add `back` event.
   */
  Drilldown.prototype._back = function($elem){
    var _this = this;
    $elem.off('click.zf.drilldown');
    $elem.children('.js-drilldown-back')
      .on('click.zf.drilldown', function(e){
        e.stopImmediatePropagation();
        // console.log('mouseup on back');
        _this._hide($elem);
      });
  };
  /**
   * Adds event listener to menu items w/o submenus to close open menus on click.
   * @function
   * @private
   */
  Drilldown.prototype._menuLinkEvents = function(){
    var _this = this;
    this.$menuItems.not('.has-submenu')
        .off('click.zf.drilldown')
        .on('click.zf.drilldown', function(e){
          // e.stopImmediatePropagation();
          setTimeout(function(){
            _this._hideAll();
          }, 0);
      });
  };
  /**
   * Opens a submenu.
   * @function
   * @fires Drilldown#open
   * @param {jQuery} $elem - the current element with a submenu to open.
   */
  Drilldown.prototype._show = function($elem){
    $elem.children('[data-submenu]').addClass('is-active');

    this.$element.trigger('open.zf.drilldown', [$elem]);
  };
  /**
   * Hides a submenu
   * @function
   * @fires Drilldown#hide
   * @param {jQuery} $elem - the current sub-menu to hide.
   */
  Drilldown.prototype._hide = function($elem){
    var _this = this;
    $elem.addClass('is-closing')
         .one(Foundation.transitionend($elem), function(){
           $elem.removeClass('is-active is-closing');
         });
    /**
     * Fires when the submenu is has closed.
     * @event Drilldown#hide
     */
    $elem.trigger('hide.zf.drilldown', [$elem]);

  };
  /**
   * Iterates through the nested menus to calculate the min-height, and max-width for the menu.
   * Prevents content jumping.
   * @function
   * @private
   */
  Drilldown.prototype._getMaxDims = function(){
    var max = 0, result = {};
    this.$submenus.add(this.$element).each(function(){
      var numOfElems = $(this).children('li').length;
      max = numOfElems > max ? numOfElems : max;
    });

    result.height = max * this.$menuItems[0].getBoundingClientRect().height + 'px';
    result.width = this.$element[0].getBoundingClientRect().width + 'px';

    return result;
  };
  /**
   * Destroys the Drilldown Menu
   * @function
   */
  Drilldown.prototype.destroy = function(){
    this._hideAll();
    Foundation.Nest.Burn(this.$element, 'drilldown');
    this.$element.unwrap()
                 .find('.js-drilldown-back').remove()
                 .end().find('.js-drilldown-parent').remove()
                 .end().find('.is-active, .is-closing, .is-drilldown-sub').removeClass('is-active is-closing is-drilldown-sub')
                 .end().find('[data-submenu]').removeAttr('aria-hidden tabindex role')
                 .off('.zf.drilldown').end().off('zf.drilldown');
    this.$element.find('a').each(function(){
      var $link = $(this);
      if($link.data('savedHref')){
        $link.attr('href', $link.data('savedHref')).removeData('savedHref');
      }else{ return; }
    });
    Foundation.unregisterPlugin(this);
  };
  Foundation.plugin(Drilldown, 'Drilldown');
}(jQuery, window.Foundation);

Endre R. Fehn commented on Guy Van Bael's post about 3 years

The following patch to foundation.drilldown.js creates a new option "parentButton". It replaces keywords #href and #txt with parent link and link text respectively.

Might not be the most elegant solution, but it seems to work. Default parentButton is blank to keep original behaviour unchanged.

 --- ~/f6/bower_components/foundation-sites/js/foundation.drilldown.js  2015-12-03 00:26:32.000000000 +0100
+++ ./foundation.drilldown.js  2015-12-08 09:29:07.000000000 +0100
@@ -43,6 +43,12 @@
      */
     backButton: '<li class="js-drilldown-back"><a>Back</a></li>',
     /**
+     * Markup used for JS generated parent button. Prepended to submenu lists and deleted on `destroy` method, 'js-drilldown-parent' class required. Remove the backslash (`\`) if copy and pasting.
+     * @option
+     * @example '<\li class="js-drilldown-parent"><\a href="#href">#txt<\/a><\/li>'
+     */
+    parentButton: '',
+    /**
      * Markup used to wrap drilldown menu. Use a class name for independent styling; the JS applied class: `is-drilldown` is required. Remove the backslash (`\`) if copy and pasting.
      * @option
      * @example '<\div class="is-drilldown"><\/div>'
@@ -95,7 +101,13 @@
     });
     this.$submenus.each(function(){
       var $menu = $(this),
-          $back = $menu.find('.js-drilldown-back');
+          $back = $menu.find('.js-drilldown-back'),
+          $parent = $menu.find('.js-drilldown-parent');
+      if (!$parent.length){
+        $menu.prepend(_this.options.parentButton
+                      .replace(/#href/g,$menu.parent().find('a:first').data('savedHref'))
+                      .replace(/#txt/g,$menu.parent().find('a:first').html()));
+      }
       if(!$back.length){
         $menu.prepend(_this.options.backButton);
         _this._back($menu);
@@ -306,6 +318,7 @@
     Foundation.Nest.Burn(this.$element, 'drilldown');
     this.$element.unwrap()
                  .find('.js-drilldown-back').remove()
+                 .end().find('.js-drilldown-parent').remove()
                  .end().find('.is-active, .is-closing, .is-drilldown-sub').removeClass('is-active is-closing is-drilldown-sub')
                  .end().find('[data-submenu]').removeAttr('aria-hidden tabindex role')
                  .off('.zf.drilldown').end().off('zf.drilldown');

Endre R. Fehn commented on Brett Mason's post about 3 years

The following patch to foundation.drilldown.js creates a new option "parentButton". It replaces keywords #href and #txt with parent link and link text respectively.

Might not be the most elegant solution, but it seems to work. Default parentButton is blank to keep original behaviour unchanged.

 --- ~/f6/bower_components/foundation-sites/js/foundation.drilldown.js  2015-12-03 00:26:32.000000000 +0100
+++ ./foundation.drilldown.js  2015-12-08 09:29:07.000000000 +0100
@@ -43,6 +43,12 @@
      */
     backButton: '<li class="js-drilldown-back"><a>Back</a></li>',
     /**
+     * Markup used for JS generated parent button. Prepended to submenu lists and deleted on `destroy` method, 'js-drilldown-parent' class required. Remove the backslash (`\`) if copy and pasting.
+     * @option
+     * @example '<\li class="js-drilldown-parent"><\a href="#href">#txt<\/a><\/li>'
+     */
+    parentButton: '',
+    /**
      * Markup used to wrap drilldown menu. Use a class name for independent styling; the JS applied class: `is-drilldown` is required. Remove the backslash (`\`) if copy and pasting.
      * @option
      * @example '<\div class="is-drilldown"><\/div>'
@@ -95,7 +101,13 @@
     });
     this.$submenus.each(function(){
       var $menu = $(this),
-          $back = $menu.find('.js-drilldown-back');
+          $back = $menu.find('.js-drilldown-back'),
+          $parent = $menu.find('.js-drilldown-parent');
+      if (!$parent.length){
+        $menu.prepend(_this.options.parentButton
+                      .replace(/#href/g,$menu.parent().find('a:first').data('savedHref'))
+                      .replace(/#txt/g,$menu.parent().find('a:first').html()));
+      }
       if(!$back.length){
         $menu.prepend(_this.options.backButton);
         _this._back($menu);
@@ -306,6 +318,7 @@
     Foundation.Nest.Burn(this.$element, 'drilldown');
     this.$element.unwrap()
                  .find('.js-drilldown-back').remove()
+                 .end().find('.js-drilldown-parent').remove()
                  .end().find('.is-active, .is-closing, .is-drilldown-sub').removeClass('is-active is-closing is-drilldown-sub')
                  .end().find('[data-submenu]').removeAttr('aria-hidden tabindex role')
                  .off('.zf.drilldown').end().off('zf.drilldown');

Posts Followed



Following

    No Content

Followers

My Posts

No Content

My Comments

You commented on Guy Van Bael's post about 3 years

A link for downloading my patched foundation.js and foundation.min.js:

https://www.dropbox.com/s/546737o4buzqp16/f_605_drilldown.zip?dl=0

I agree this was an unfortunate omission, but for me there are too many other good improvements to skip v. 6. This is one that will be included shortly I guess.

You commented on Guy Van Bael's post about 3 years

Here is the patched foundation.drilldown.js -- if you include foundation.js in you project, the same changes needs to be made in foundation.js (and foundation.min.js).

 /**
 * Drilldown module.
 * @module foundation.drilldown
 * @requires foundation.util.keyboard
 * @requires foundation.util.motion
 * @requires foundation.util.nest
 */
!function($, Foundation){
  'use strict';

  /**
   * Creates a new instance of a drilldown menu.
   * @class
   * @param {jQuery} element - jQuery object to make into an accordion menu.
   * @param {Object} options - Overrides to the default plugin settings.
   */
  function Drilldown(element, options){
    this.$element = element;
    this.options = $.extend({}, Drilldown.defaults, this.$element.data(), options);

    Foundation.Nest.Feather(this.$element, 'drilldown');

    this._init();

    Foundation.registerPlugin(this);
    Foundation.Keyboard.register('Drilldown', {
      'ENTER': 'open',
      'SPACE': 'open',
      'ARROW_RIGHT': 'next',
      'ARROW_UP': 'up',
      'ARROW_DOWN': 'down',
      'ARROW_LEFT': 'previous',
      'ESCAPE': 'close',
      'TAB': 'down',
      'SHIFT_TAB': 'up'
    });
  }
  Drilldown.defaults = {
    /**
     * Markup used for JS generated back button. Prepended to submenu lists and deleted on `destroy` method, 'js-drilldown-back' class required. Remove the backslash (`\`) if copy and pasting.
     * @option
     * @example '<\li><\a>Back<\/a><\/li>'
     */
    backButton: '<li class="js-drilldown-back"><a>Back</a></li>',
    /**
     * Markup used for JS generated parent button. Prepended to submenu lists and deleted on `destroy` method, 'js-drilldown-parent' class required. Remove the backslash (`\`) if copy and pasting.
     * @option
     * @example '<\li class="js-drilldown-parent"><\a href="#href">#txt<\/a><\/li>'
     */
    parentButton: '',
    /**
     * Markup used to wrap drilldown menu. Use a class name for independent styling; the JS applied class: `is-drilldown` is required. Remove the backslash (`\`) if copy and pasting.
     * @option
     * @example '<\div class="is-drilldown"><\/div>'
     */
    wrapper: '<div></div>',
    /**
     * Allow the menu to return to root list on body click.
     * @option
     * @example false
     */
    closeOnClick: false
    // holdOpen: false
  };
  /**
   * Initializes the drilldown by creating jQuery collections of elements
   * @private
   */
  Drilldown.prototype._init = function(){
    this.$submenuAnchors = this.$element.find('li.has-submenu');
    this.$submenus = this.$submenuAnchors.children('[data-submenu]');
    this.$menuItems = this.$element.find('li:visible').not('.js-drilldown-back').attr('role', 'menuitem');

    this._prepareMenu();

    this._keyboardEvents();
  };
  /**
   * prepares drilldown menu by setting attributes to links and elements
   * sets a min height to prevent content jumping
   * wraps the element if not already wrapped
   * @private
   * @function
   */
  Drilldown.prototype._prepareMenu = function(){
    var _this = this;
    // if(!this.options.holdOpen){
    //   this._menuLinkEvents();
    // }
    this.$submenuAnchors.each(function(){
      var $sub = $(this);
      var $link = $sub.find('a:first');
      $link.data('savedHref', $link.attr('href')).removeAttr('href');
      $sub.children('[data-submenu]')
          .attr({
            'aria-hidden': true,
            'tabindex': 0,
            'role': 'menu'
          });
      _this._events($sub);
    });
    this.$submenus.each(function(){
      var $menu = $(this),
          $back = $menu.find('.js-drilldown-back'),
          $parent = $menu.find('.js-drilldown-parent');
      if (!$parent.length){
        $menu.prepend(_this.options.parentButton
                      .replace(/#href/g,$menu.parent().find('a:first').data('savedHref'))
                      .replace(/#txt/g,$menu.parent().find('a:first').html()));
      }
      if(!$back.length){
        $menu.prepend(_this.options.backButton);
        _this._back($menu);
      }
    });
    if(!this.$element.parent().hasClass('is-drilldown')){
      this.$wrapper = $(this.options.wrapper).addClass('is-drilldown').css(this._getMaxDims());
      this.$element.wrap(this.$wrapper);
    }

  };
  /**
   * Adds event handlers to elements in the menu.
   * @function
   * @private
   * @param {jQuery} $elem - the current menu item to add handlers to.
   */
  Drilldown.prototype._events = function($elem){
    var _this = this;

    $elem.off('click.zf.drilldown')
    .on('click.zf.drilldown', function(e){
      if($(e.target).parentsUntil('ul', 'li').hasClass('is-drilldown-submenu-parent')){
        e.stopImmediatePropagation();
        e.preventDefault();
      }

      // if(e.target !== e.currentTarget.firstElementChild){
      //   return false;
      // }
      _this._show($elem);

      if(_this.options.closeOnClick){
        var $body = $('body').not(_this.$wrapper);
        $body.off('.zf.drilldown').on('click.zf.drilldown', function(e){
          e.preventDefault();
          _this._hideAll();
          $body.off('.zf.drilldown');
        });
      }
    });
  };
  /**
   * Adds keydown event listener to `li`'s in the menu.
   * @private
   */
  Drilldown.prototype._keyboardEvents = function() {
    var _this = this;
    this.$menuItems.add(this.$element.find('.js-drilldown-back')).on('keydown.zf.drilldown', function(e){
      var $element = $(this),
          $elements = $element.parent('ul').children('li'),
          $prevElement,
          $nextElement;

      $elements.each(function(i) {
        if ($(this).is($element)) {
          $prevElement = $elements.eq(Math.max(0, i-1));
          $nextElement = $elements.eq(Math.min(i+1, $elements.length-1));
          return;
        }
      });
      Foundation.Keyboard.handleKey(e, _this, {
        next: function() {
          if ($element.is(_this.$submenuAnchors)) {
            _this._show($element);
            $element.on(Foundation.transitionend($element), function(){
              $element.find('ul li').filter(_this.$menuItems).first().focus();
            });
          }
        },
        previous: function() {
          _this._hide($element.parent('ul'));
          $element.parent('ul').on(Foundation.transitionend($element), function(){
            setTimeout(function() {
              $element.parent('ul').parent('li').focus();
            }, 1);
          });
        },
        up: function() {
          $prevElement.focus();
        },
        down: function() {
          $nextElement.focus();
        },
        close: function() {
          _this._back();
          //_this.$menuItems.first().focus(); // focus to first element
        },
        open: function() {
          if (!$element.is(_this.$menuItems)) { // not menu item means back button
            _this._hide($element.parent('ul'));
            setTimeout(function(){$element.parent('ul').parent('li').focus();}, 1);
          } else if ($element.is(_this.$submenuAnchors)) {
            _this._show($element);
            setTimeout(function(){$element.find('ul li').filter(_this.$menuItems).first().focus();}, 1);
          }
        },
        handled: function() {
          e.preventDefault();
          e.stopImmediatePropagation();
        }
      });
    }); // end keyboardAccess
  };

  /**
   * Closes all open elements, and returns to root menu.
   * @function
   * @fires Drilldown#closed
   */
  Drilldown.prototype._hideAll = function(){
    var $elem = this.$element.find('.is-drilldown-sub.is-active').addClass('is-closing');
    $elem.one(Foundation.transitionend($elem), function(e){
      $elem.removeClass('is-active is-closing');
    });
        /**
         * Fires when the menu is fully closed.
         * @event Drilldown#closed
         */
    this.$element.trigger('closed.zf.drilldown');
  };
  /**
   * Adds event listener for each `back` button, and closes open menus.
   * @function
   * @fires Drilldown#back
   * @param {jQuery} $elem - the current sub-menu to add `back` event.
   */
  Drilldown.prototype._back = function($elem){
    var _this = this;
    $elem.off('click.zf.drilldown');
    $elem.children('.js-drilldown-back')
      .on('click.zf.drilldown', function(e){
        e.stopImmediatePropagation();
        // console.log('mouseup on back');
        _this._hide($elem);
      });
  };
  /**
   * Adds event listener to menu items w/o submenus to close open menus on click.
   * @function
   * @private
   */
  Drilldown.prototype._menuLinkEvents = function(){
    var _this = this;
    this.$menuItems.not('.has-submenu')
        .off('click.zf.drilldown')
        .on('click.zf.drilldown', function(e){
          // e.stopImmediatePropagation();
          setTimeout(function(){
            _this._hideAll();
          }, 0);
      });
  };
  /**
   * Opens a submenu.
   * @function
   * @fires Drilldown#open
   * @param {jQuery} $elem - the current element with a submenu to open.
   */
  Drilldown.prototype._show = function($elem){
    $elem.children('[data-submenu]').addClass('is-active');

    this.$element.trigger('open.zf.drilldown', [$elem]);
  };
  /**
   * Hides a submenu
   * @function
   * @fires Drilldown#hide
   * @param {jQuery} $elem - the current sub-menu to hide.
   */
  Drilldown.prototype._hide = function($elem){
    var _this = this;
    $elem.addClass('is-closing')
         .one(Foundation.transitionend($elem), function(){
           $elem.removeClass('is-active is-closing');
         });
    /**
     * Fires when the submenu is has closed.
     * @event Drilldown#hide
     */
    $elem.trigger('hide.zf.drilldown', [$elem]);

  };
  /**
   * Iterates through the nested menus to calculate the min-height, and max-width for the menu.
   * Prevents content jumping.
   * @function
   * @private
   */
  Drilldown.prototype._getMaxDims = function(){
    var max = 0, result = {};
    this.$submenus.add(this.$element).each(function(){
      var numOfElems = $(this).children('li').length;
      max = numOfElems > max ? numOfElems : max;
    });

    result.height = max * this.$menuItems[0].getBoundingClientRect().height + 'px';
    result.width = this.$element[0].getBoundingClientRect().width + 'px';

    return result;
  };
  /**
   * Destroys the Drilldown Menu
   * @function
   */
  Drilldown.prototype.destroy = function(){
    this._hideAll();
    Foundation.Nest.Burn(this.$element, 'drilldown');
    this.$element.unwrap()
                 .find('.js-drilldown-back').remove()
                 .end().find('.js-drilldown-parent').remove()
                 .end().find('.is-active, .is-closing, .is-drilldown-sub').removeClass('is-active is-closing is-drilldown-sub')
                 .end().find('[data-submenu]').removeAttr('aria-hidden tabindex role')
                 .off('.zf.drilldown').end().off('zf.drilldown');
    this.$element.find('a').each(function(){
      var $link = $(this);
      if($link.data('savedHref')){
        $link.attr('href', $link.data('savedHref')).removeData('savedHref');
      }else{ return; }
    });
    Foundation.unregisterPlugin(this);
  };
  Foundation.plugin(Drilldown, 'Drilldown');
}(jQuery, window.Foundation);

You commented on Guy Van Bael's post about 3 years

The following patch to foundation.drilldown.js creates a new option "parentButton". It replaces keywords #href and #txt with parent link and link text respectively.

Might not be the most elegant solution, but it seems to work. Default parentButton is blank to keep original behaviour unchanged.

 --- ~/f6/bower_components/foundation-sites/js/foundation.drilldown.js  2015-12-03 00:26:32.000000000 +0100
+++ ./foundation.drilldown.js  2015-12-08 09:29:07.000000000 +0100
@@ -43,6 +43,12 @@
      */
     backButton: '<li class="js-drilldown-back"><a>Back</a></li>',
     /**
+     * Markup used for JS generated parent button. Prepended to submenu lists and deleted on `destroy` method, 'js-drilldown-parent' class required. Remove the backslash (`\`) if copy and pasting.
+     * @option
+     * @example '<\li class="js-drilldown-parent"><\a href="#href">#txt<\/a><\/li>'
+     */
+    parentButton: '',
+    /**
      * Markup used to wrap drilldown menu. Use a class name for independent styling; the JS applied class: `is-drilldown` is required. Remove the backslash (`\`) if copy and pasting.
      * @option
      * @example '<\div class="is-drilldown"><\/div>'
@@ -95,7 +101,13 @@
     });
     this.$submenus.each(function(){
       var $menu = $(this),
-          $back = $menu.find('.js-drilldown-back');
+          $back = $menu.find('.js-drilldown-back'),
+          $parent = $menu.find('.js-drilldown-parent');
+      if (!$parent.length){
+        $menu.prepend(_this.options.parentButton
+                      .replace(/#href/g,$menu.parent().find('a:first').data('savedHref'))
+                      .replace(/#txt/g,$menu.parent().find('a:first').html()));
+      }
       if(!$back.length){
         $menu.prepend(_this.options.backButton);
         _this._back($menu);
@@ -306,6 +318,7 @@
     Foundation.Nest.Burn(this.$element, 'drilldown');
     this.$element.unwrap()
                  .find('.js-drilldown-back').remove()
+                 .end().find('.js-drilldown-parent').remove()
                  .end().find('.is-active, .is-closing, .is-drilldown-sub').removeClass('is-active is-closing is-drilldown-sub')
                  .end().find('[data-submenu]').removeAttr('aria-hidden tabindex role')
                  .off('.zf.drilldown').end().off('zf.drilldown');

You commented on Brett Mason's post about 3 years

The following patch to foundation.drilldown.js creates a new option "parentButton". It replaces keywords #href and #txt with parent link and link text respectively.

Might not be the most elegant solution, but it seems to work. Default parentButton is blank to keep original behaviour unchanged.

 --- ~/f6/bower_components/foundation-sites/js/foundation.drilldown.js  2015-12-03 00:26:32.000000000 +0100
+++ ./foundation.drilldown.js  2015-12-08 09:29:07.000000000 +0100
@@ -43,6 +43,12 @@
      */
     backButton: '<li class="js-drilldown-back"><a>Back</a></li>',
     /**
+     * Markup used for JS generated parent button. Prepended to submenu lists and deleted on `destroy` method, 'js-drilldown-parent' class required. Remove the backslash (`\`) if copy and pasting.
+     * @option
+     * @example '<\li class="js-drilldown-parent"><\a href="#href">#txt<\/a><\/li>'
+     */
+    parentButton: '',
+    /**
      * Markup used to wrap drilldown menu. Use a class name for independent styling; the JS applied class: `is-drilldown` is required. Remove the backslash (`\`) if copy and pasting.
      * @option
      * @example '<\div class="is-drilldown"><\/div>'
@@ -95,7 +101,13 @@
     });
     this.$submenus.each(function(){
       var $menu = $(this),
-          $back = $menu.find('.js-drilldown-back');
+          $back = $menu.find('.js-drilldown-back'),
+          $parent = $menu.find('.js-drilldown-parent');
+      if (!$parent.length){
+        $menu.prepend(_this.options.parentButton
+                      .replace(/#href/g,$menu.parent().find('a:first').data('savedHref'))
+                      .replace(/#txt/g,$menu.parent().find('a:first').html()));
+      }
       if(!$back.length){
         $menu.prepend(_this.options.backButton);
         _this._back($menu);
@@ -306,6 +318,7 @@
     Foundation.Nest.Burn(this.$element, 'drilldown');
     this.$element.unwrap()
                  .find('.js-drilldown-back').remove()
+                 .end().find('.js-drilldown-parent').remove()
                  .end().find('.is-active, .is-closing, .is-drilldown-sub').removeClass('is-active is-closing is-drilldown-sub')
                  .end().find('[data-submenu]').removeAttr('aria-hidden tabindex role')
                  .off('.zf.drilldown').end().off('zf.drilldown');

Posts Followed

Following

  • No Content

Followers

  • No Content