From d73157a75bba980aae01c3ac14fcb67a5933de22 Mon Sep 17 00:00:00 2001 From: eoghan Date: Tue, 29 Aug 2017 10:23:37 +0000 Subject: [PATCH 1/2] Enable nested dropdowns --- jquery.dropdown.js | 53 +++++++++++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 22 deletions(-) diff --git a/jquery.dropdown.js b/jquery.dropdown.js index f83f239..ffccd56 100644 --- a/jquery.dropdown.js +++ b/jquery.dropdown.js @@ -48,7 +48,7 @@ if (jQuery) (function ($) { } else { if (trigger !== object.target && $(object.target).hasClass('jq-dropdown-ignore')) return; } - hide(); + hide(event); if (isOpen || trigger.hasClass('jq-dropdown-disabled')) return; @@ -75,50 +75,59 @@ if (jQuery) (function ($) { // In some cases we don't hide them var targetGroup = event ? $(event.target).parents().addBack() : null; - // Are we clicking anywhere in a jq-dropdown? - if (targetGroup && targetGroup.is('.jq-dropdown')) { - // Is it a jq-dropdown menu? - if (targetGroup.is('.jq-dropdown-menu')) { - // Did we click on an option? If so close it. - if (!targetGroup.is('A')) return; - } else { - // Nope, it's a panel. Leave it open. - return; - } + // hide other dropdowns, but not the one we've clicked within + var toHide = $(document).find('.jq-dropdown:visible').not( + $(event.target).parents('.jq-dropdown')); + + if (targetGroup && targetGroup.is('.jq-dropdown') && + targetGroup.is('.jq-dropdown-menu') && + targetGroup.is('A')) { + // Clicked an option within the current dropdown + // If this is a nested dropdown, make sure to keep the parent dropdown open + toHide = $(event.target).closest('.jq-dropdown:visible') } // Trigger the event early, so that it might be prevented on the visible popups var hideEvent = jQuery.Event("hide"); - $(document).find('.jq-dropdown:visible').each(function () { + + toHide.each(function () { var jqDropdown = $(this); jqDropdown .hide() - .removeData('jq-dropdown-trigger') .trigger('hide', { jqDropdown: jqDropdown }); }); if(!hideEvent.isDefaultPrevented()) { // Hide any jq-dropdown that may be showing - $(document).find('.jq-dropdown:visible').each(function () { + toHide.each(function () { + // Remove all jq-dropdown-open classes var jqDropdown = $(this); + var trigger = jqDropdown.data('jq-dropdown-trigger'); + trigger.removeClass('jq-dropdown-open'); jqDropdown .hide() .removeData('jq-dropdown-trigger') .trigger('hide', { jqDropdown: jqDropdown }); }); - - // Remove all jq-dropdown-open classes - $(document).find('.jq-dropdown-open').removeClass('jq-dropdown-open'); } } function position() { + $('.jq-dropdown:visible').each(function() { + positionDropdown($(this)); + }); + } + + function positionDropdown(jqDropdown) { + + var trigger = jqDropdown.data('jq-dropdown-trigger'); + if (!trigger) { + return; + } - var jqDropdown = $('.jq-dropdown:visible').eq(0), - trigger = jqDropdown.data('jq-dropdown-trigger'), - hOffset = trigger ? parseInt(trigger.attr('data-horizontal-offset') || 0, 10) : null, - vOffset = trigger ? parseInt(trigger.attr('data-vertical-offset') || 0, 10) : null; + var hOffset = parseInt(trigger.attr('data-horizontal-offset') || 0, 10), + vOffset = parseInt(trigger.attr('data-vertical-offset') || 0, 10); if (jqDropdown.length === 0 || !trigger) return; @@ -144,4 +153,4 @@ if (jQuery) (function ($) { $(document).on('click.jq-dropdown', hide); $(window).on('resize', position); -})(jQuery); \ No newline at end of file +})(jQuery); From 587c9dcbf46b5c6dac9ca0ba5c7717e2059b95aa Mon Sep 17 00:00:00 2001 From: eoghan Date: Tue, 29 Aug 2017 15:09:42 +0000 Subject: [PATCH 2/2] triggerHandler rather than trigger ensures that when the nested dropdown is shown, the parent dropdown's 'show' handlers don't unintentionally fire --- jquery.dropdown.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/jquery.dropdown.js b/jquery.dropdown.js index ffccd56..73b5725 100644 --- a/jquery.dropdown.js +++ b/jquery.dropdown.js @@ -63,7 +63,7 @@ if (jQuery) (function ($) { // Trigger the show callback jqDropdown - .trigger('show', { + .triggerHandler('show', { jqDropdown: jqDropdown, trigger: trigger }); @@ -95,7 +95,7 @@ if (jQuery) (function ($) { var jqDropdown = $(this); jqDropdown .hide() - .trigger('hide', { jqDropdown: jqDropdown }); + .triggerHandler('hide', { jqDropdown: jqDropdown }); }); if(!hideEvent.isDefaultPrevented()) { @@ -108,7 +108,7 @@ if (jQuery) (function ($) { jqDropdown .hide() .removeData('jq-dropdown-trigger') - .trigger('hide', { jqDropdown: jqDropdown }); + .triggerHandler('hide', { jqDropdown: jqDropdown }); }); } }