Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for Submenus #123

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 69 additions & 3 deletions index.html
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,13 @@ <h3>Panels</h3>
<p>
Dropdowns can have regular HTML, too. <span class="example" data-jq-dropdown="#jq-dropdown-6">Example</span>
</p>
<h3>Submenus</h3>
<p>
You can add submenus to your dropdowns: <span class="example" data-jq-dropdown="#jq-dropdown-multiA">Click Me</span>
</p>
<p>
Dropdowns can be set up to stay open if an item from a submenu is selected: <span class="example" data-jq-dropdown="#jq-dropdown-multiD">Click Me</span>
</p>

<h3>Special Classes</h3>
<ul>
Expand All @@ -190,8 +197,9 @@ <h3>Special Classes</h3>
<li>To add a tip to the jq-dropdown, add the <code>jq-dropdown-tip</code> class to the jq-dropdown element</li>
<li>To make the jq-dropdown anchor to the right, add the <code>jq-dropdown-anchor-right</code> class: <span class="example" data-jq-dropdown="#jq-dropdown-4">Example</span></li>
<li>To position a jq-dropdown relative to its parent (as opposed to the document), add the <code>jq-dropdown-relative</code> class to the jq-dropdown container</li>
<li>To have a dropdown menu stay open when a child submenu option is selected, add the <code>jq-dropdown-keep-parent-menu</code> class to the parent jq-dropdown container</li>
</ul>

<h2>API</h2>
<p>
You probably won’t need these, but they’re there just in case:
Expand Down Expand Up @@ -239,8 +247,8 @@ <h2>Q&amp;A</h2>
</li>
<li>
<strong>Do they support submenus?</strong><br />
No, and they aren’t intended to. That would add a significant amount of complexity to the plugin and is really
outside the scope of this project.
Yes, <a href="https://github.com/mjgood/jquery-dropdown/tree/child-menus-mjgood">mjgood</a>'s branch adds some
support for them.
</li>
<li>
<strong>Can I get rid of the tips?</strong><br />
Expand Down Expand Up @@ -268,6 +276,64 @@ <h2>Q&amp;A</h2>


<!-- Remember to put your jq-dropdown menus before your ending BODY tag -->
<div id="jq-dropdown-multiA" class="jq-dropdown jq-dropdown-tip">
<ul class="jq-dropdown-menu">
<li><p class="example" style="margin-left:20px;" data-jq-dropdown="#jq-dropdown-multiC">Item 1</p></li>
<li><p class="example" style="margin-left:20px;" data-jq-dropdown="#jq-dropdown-multiC">Item 2</p></li>
<li><p class="example" style="margin-left:20px;" data-jq-dropdown="#jq-dropdown-multiC">Item 3</p></li>
<li class="jq-dropdown-divider"></li>
<li><p class="example" style="margin-left:20px;" data-jq-dropdown="#jq-dropdown-multiB">Item 4</p></li>
<li><p class="example" style="margin-left:20px;" data-jq-dropdown="#jq-dropdown-multiB">Item 5</p></li>
<li><p class="example" style="margin-left:20px;" data-jq-dropdown="#jq-dropdown-multiB">Item 6</p></li>
</ul>
</div>

<div id="jq-dropdown-multiB" class="jq-dropdown jq-dropdown-tip">
<ul class="jq-dropdown-menu">
<li><p class="example" style="margin-left:20px;" data-jq-dropdown="#jq-dropdown-multiC">D</p></li>
<li><p class="example" style="margin-left:20px;" data-jq-dropdown="#jq-dropdown-multiC">E</p></li>
<li><p class="example" style="margin-left:20px;" data-jq-dropdown="#jq-dropdown-multiC">F</p></li>
</ul>
</div>

<div id="jq-dropdown-multiC" class="jq-dropdown jq-dropdown-tip">
<ul class="jq-dropdown-menu">
<li><a href="#1">Item 1</a></li>
<li><a href="#2">Item 2</a></li>
<li><a href="#3">Item 3</a></li>
</ul>
</div>

<div id="jq-dropdown-multiD" class="jq-dropdown jq-dropdown-tip jq-dropdown-keep-parent-menu">
<ul class="jq-dropdown-menu">
<li><p class="example" style="margin-left:20px;" data-jq-dropdown="#jq-dropdown-multiE">Item 1</p></li>
<li><p class="example" style="margin-left:20px;" data-jq-dropdown="#jq-dropdown-multiF">Item 2</p></li>
<li><p class="example" style="margin-left:20px;" data-jq-dropdown="#jq-dropdown-multiG">Item 3</p></li>
</ul>
<div id="jq-dropdown-multiE" class="jq-dropdown jq-dropdown-tip jq-dropdown-relative">
<ul class="jq-dropdown-menu">
<li><a href="#1">Item 1</a></li>
<li><a href="#2">Item 2</a></li>
<li><a href="#3">Item 3</a></li>
</ul>
</div>
<div id="jq-dropdown-multiF" class="jq-dropdown jq-dropdown-tip jq-dropdown-relative">
<ul class="jq-dropdown-menu">
<li><a href="#1">Item 1</a></li>
<li><a href="#2">Item 2</a></li>
<li><a href="#3">Item 3</a></li>
</ul>
</div>
<div id="jq-dropdown-multiG" class="jq-dropdown jq-dropdown-tip jq-dropdown-relative">
<ul class="jq-dropdown-menu">
<li><a href="#1">Item 1</a></li>
<li><a href="#2">Item 2</a></li>
<li><a href="#3">Item 3</a></li>
</ul>
</div>
</div>


<div id="jq-dropdown-1" class="jq-dropdown jq-dropdown-tip">
<ul class="jq-dropdown-menu">
<li><a href="#1">Item 1</a></li>
Expand Down
83 changes: 61 additions & 22 deletions jquery.dropdown.js
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,7 @@ if (jQuery) (function ($) {
function show(event, object) {

var trigger = event ? $(this) : object,
jqDropdown = $(trigger.attr('data-jq-dropdown')),
isOpen = trigger.hasClass('jq-dropdown-open');
jqDropdown = $(trigger.attr('data-jq-dropdown'));

// In some cases we don't want to show it
if (event) {
Expand All @@ -48,32 +47,53 @@ if (jQuery) (function ($) {
} else {
if (trigger !== object.target && $(object.target).hasClass('jq-dropdown-ignore')) return;
}
hide();

// Mark parent jq-dropdown-open classes to be kept
var dropdownParents = $(event.target).parents();
var maxParent = 0;
for (var i = 0; i < dropdownParents.length; i++) {
var check = $(dropdownParents[i]).attr('jq-dropdown-menu-order')
if (check != null && parseInt(check) > maxParent) {
maxParent = parseInt(check);
}
}

// hide all the menus that are a child of the parent
var hideEvent = jQuery.Event('hide', {'childrenMenusOf' : maxParent });
jQuery('body').trigger(hideEvent);

hide(hideEvent);

if (isOpen || trigger.hasClass('jq-dropdown-disabled')) return;
if (trigger.hasClass('jq-dropdown-disabled')) return;

// Show it
trigger.addClass('jq-dropdown-open');
trigger.addClass('jq-dropdown-open');
trigger.attr('jq-dropdown-menu-order', (maxParent + 1));
jqDropdown
.attr('jq-dropdown-menu-order', (maxParent + 1))
.data('jq-dropdown-trigger', trigger)
.show();

// Position it
position();
position((maxParent + 1));

// Trigger the show callback
jqDropdown
.trigger('show', {
jqDropdown: jqDropdown,
trigger: trigger
});

}

function hide(event) {

// In some cases we don't hide them
var targetGroup = event ? $(event.target).parents().addBack() : null;
var parentMenu = null;
if (event.hasOwnProperty('childrenMenusOf')) {
parentMenu = event.childrenMenusOf;
}

// Are we clicking anywhere in a jq-dropdown?
if (targetGroup && targetGroup.is('.jq-dropdown')) {
Expand All @@ -86,36 +106,55 @@ if (jQuery) (function ($) {
return;
}
}

// If the dropdown is a child of another dropdown and the parent dropdown is marked to stay open
if (parentMenu == null) {
var parentToKeep = targetGroup.filter('.jq-dropdown-keep-parent-menu');
if (parentToKeep[0] != null) {
parentMenu = parseInt($(parentToKeep[0]).attr('jq-dropdown-menu-order'));
}
}

// Trigger the event early, so that it might be prevented on the visible popups
var hideEvent = jQuery.Event("hide");
var hideEvent = jQuery.Event("hide", {'childrenMenusOf' : parentMenu });

$(document).find('.jq-dropdown:visible').each(function () {
var jqDropdown = $(this);
jqDropdown
.hide()
.removeData('jq-dropdown-trigger')
.trigger('hide', { jqDropdown: jqDropdown });
if (parentMenu == null || parseInt(jqDropdown.attr('jq-dropdown-menu-order')) > parentMenu) {
jqDropdown
.hide()
.removeData('jq-dropdown-trigger')
.removeAttr('jq-dropdown-menu-order')
.trigger('hide', { jqDropdown: jqDropdown, 'childrenMenusOf': parentMenu });
}
});

if(!hideEvent.isDefaultPrevented()) {
// Hide any jq-dropdown that may be showing
$(document).find('.jq-dropdown:visible').each(function () {
var jqDropdown = $(this);
jqDropdown
.hide()
.removeData('jq-dropdown-trigger')
.trigger('hide', { jqDropdown: jqDropdown });
if (parentMenu == null || parseInt(jqDropdown.attr('jq-dropdown-menu-order')) > parentMenu) {
jqDropdown
.hide()
.removeData('jq-dropdown-trigger')
.trigger('hide', { jqDropdown: jqDropdown, 'childrenMenusOf': parentMenu });
}
});

// Remove all jq-dropdown-open classes and jq-dropdown-menu-order attributes
$(document).find('.jq-dropdown-open').each(function () {
var jqTrigger = $(this);
if (parentMenu == null || parseInt(jqTrigger.attr('jq-dropdown-menu-order')) > parentMenu) {
jqTrigger
.removeAttr('jq-dropdown-menu-order')
.removeClass('jq-dropdown-open');
}
});

// Remove all jq-dropdown-open classes
$(document).find('.jq-dropdown-open').removeClass('jq-dropdown-open');
}
}

function position() {

var jqDropdown = $('.jq-dropdown:visible').eq(0),
function position(childMenu) {
var jqDropdown = $("[jq-dropdown-menu-order=" + childMenu + "]").filter(".jq-dropdown"),
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;
Expand Down Expand Up @@ -144,4 +183,4 @@ if (jQuery) (function ($) {
$(document).on('click.jq-dropdown', hide);
$(window).on('resize', position);

})(jQuery);
})(jQuery);
2 changes: 1 addition & 1 deletion jquery.dropdown.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.