Tim Marshall Tim Marshall - 6 months ago 41
Javascript Question

JQuery contextmenu show/hide problems

I'm working on my admin panel, the mail system section and I am finding inspiration from Outlook.com. I have added three custom right-click hijack menus alike Outlook;


  1. Right-Click Mail Nav First-Tier

  2. Right-Click Mail Nav Second-Tier

  3. Right-Click Message List



For the right-clicking of the message list, the last visible option I am trying to make it so that upon clicking ("DropMenu") the four additional options show ("ForThisSenderMore") keeping it so that click elsewhere will remove the menu unless you click on "Title" or "DropMenu".



// Trigger action when the contexmenu is about to be shown
$('ul.inbox-nav > li > a').bind("contextmenu", function (event) {

event.preventDefault();
$("#MailMenuFirstTier").finish().toggle(100).

css({
top: event.pageY + "px",
left: event.pageX + "px"
});
});
$('ul.inbox-nav > li > ul > li a').bind("contextmenu", function (event) {

event.preventDefault();
$("#MailMenuSecondTier").finish().toggle(100).

css({
top: event.pageY + "px",
left: event.pageX + "px"
});
});
$('.table>tbody>tr>td').bind("contextmenu", function (event) {

event.preventDefault();
$("#MailBodyList").finish().toggle(100).

css({
top: event.pageY + "px",
left: event.pageX + "px"
});
});


// If the Element is clicked somewhere
$('ul.inbox-nav > li > a').bind("mousedown", function (e) {
if (!$(e.target).parents(".custom-menu").length > 0) {
$("#MailMenuFirstTier").hide(100);
}
});
$('ul.inbox-nav > li > ul > li').bind("mousedown", function (e) {
if (!$(e.target).parents(".custom-menu").length > 0) {
$("#MailMenuSecondTier").hide(100);
}
});
$('.table>tbody>tr>td').bind("mousedown", function (e) {
if (!$(e.target).parents(".custom-menu").length > 0) {
$("#MailBodyList").hide(100);
}
});

jQuery(document).click(function(event) {
if (jQuery(event.target).closest('ul.inbox-nav > li > a').length === 0) {
jQuery('#MailMenuFirstTier').hide();
}
if (jQuery(event.target).closest('ul.inbox-nav > li > ul > li a').length === 0) {
jQuery('#MailMenuSecondTier').hide();
}
if (jQuery(event.target).closest('.table>tbody>tr>td').length === 0) {
jQuery('#MailBodyList').hide();
}
});
jQuery(document).on("contextmenu",function(e){
if (jQuery(event.target).closest('ul.inbox-nav > li > a').length === 0) {
$('#MailMenuFirstTier').hide();
}
if (jQuery(event.target).closest('ul.inbox-nav > li > ul > li a').length === 0) {
$('#MailMenuSecondTier').hide();
}
if (jQuery(event.target).closest('.table>tbody>tr>td').length === 0) {
$('#MailBodyList').hide();
}
});

$("#MailBodyList .DropMenu").click(function(e) {
$('.ForThisSenderMore').show();
});

.custom-menu {
display: none;
z-index: 1000;
position: absolute;
margin:0;
padding:0;
list-style:none;
overflow: hidden;
border: 1px solid #CCC;
white-space: nowrap;
font-family: sans-serif;
background: #FFF;
color: #333;
border-radius: 5px;
font-size:12px;
}

.custom-menu li {
padding: 8px 12px;
cursor: pointer;
}

.custom-menu li:hover {
background-color: #DEF;
}
.custom-menu .divider {
content:" ";
height:1px;
margin:4px 10px;
background:#929292;
}
#MailBodyList.custom-menu li.Title {
color:#929292;
}
#MailBodyList.custom-menu li.Title:hover {
background: #FFF;
cursor:default;
}
#MailBodyList.custom-menu li.ForThisSenderMore {
display:none;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<table class="table">
<tbody>
<tr>
<td> Right click me</td>
</tr>
</tbody>
</table>

<ul class="custom-menu" id="MailMenuFirstTier">
<li>New Sub-Folder</li>
<li>Mark All As Read</li>
<li>Empty Folder</li>
</ul>
<ul class="custom-menu" id="MailMenuSecondTier">
<li>New Sub-Folder</li>
<li>Rename</li>
<li>Delete</li>
<li>Mark All As Read</li>
<li>Empty Folder</li>
</ul>
<ul class="custom-menu" id="MailBodyList">
<li class="Title">For This Message</li>
<li>Reply</li>
<li>Reply All</li>
<li>Forward</li>
<div class="divider"></div>
<li>Mark As unread</li>
<li>Delete</li>
<li>Archive</li>
<li>Junk</li>
<li>Move</li>
<li>Create Rule</li>
<li>Save To BananzaCloud</li>
<li>View Message Source</li>
<div class="divider"></div>
<li class="DropMenu">For This Sender</li>
<li class="ForThisSenderMore">Send Email</li>
<li class="ForThisSenderMore">Find Email</li>
<li class="ForThisSenderMore">Move All Emails From...</li>
<li class="ForThisSenderMore">Delete All From...</li>
</ul>




Answer

This is just a super quick answer, I'll go through and refactor / clean it up for you in a bit, but the you almost had it. In your $("#MailBodyList .DropMenu").click... all you had to do was call e.stopPropagation(); This prevents the click event from chaining up into the dropdown (which is told to hide when something is clicked).

// Trigger action when the contexmenu is about to be shown
$('ul.inbox-nav > li > a').bind("contextmenu", function(event) {

  event.preventDefault();
  $("#MailMenuFirstTier").finish().toggle(100).

  css({
    top: event.pageY + "px",
    left: event.pageX + "px"
  });
});
$('ul.inbox-nav > li > ul > li a').bind("contextmenu", function(event) {

  event.preventDefault();
  $("#MailMenuSecondTier").finish().toggle(100).

  css({
    top: event.pageY + "px",
    left: event.pageX + "px"
  });
});
$('.table>tbody>tr>td').bind("contextmenu", function(event) {

  event.preventDefault();
  $("#MailBodyList").finish().toggle(100).

  css({
    top: event.pageY + "px",
    left: event.pageX + "px"
  });
});


// If the Element is clicked somewhere
$('ul.inbox-nav > li > a').bind("mousedown", function(e) {
  if (!$(e.target).parents(".custom-menu").length > 0) {
    $("#MailMenuFirstTier").hide(100);
  }
});
$('ul.inbox-nav > li > ul > li').bind("mousedown", function(e) {
  if (!$(e.target).parents(".custom-menu").length > 0) {
    $("#MailMenuSecondTier").hide(100);
  }
});
$('.table>tbody>tr>td').bind("mousedown", function(e) {
  if (!$(e.target).parents(".custom-menu").length > 0) {
    $("#MailBodyList").hide(100);
  }
});

jQuery(document).click(function(event) {
  if (jQuery(event.target).closest('ul.inbox-nav > li > a').length === 0) {
    jQuery('#MailMenuFirstTier').hide();
  }
  if (jQuery(event.target).closest('ul.inbox-nav > li > ul > li a').length === 0) {
    jQuery('#MailMenuSecondTier').hide();
  }
  if (jQuery(event.target).closest('.table>tbody>tr>td').length === 0) {
    jQuery('#MailBodyList').hide();
  }
});
jQuery(document).on("contextmenu", function(e) {
  if (jQuery(event.target).closest('ul.inbox-nav > li > a').length === 0) {
    $('#MailMenuFirstTier').hide();
  }
  if (jQuery(event.target).closest('ul.inbox-nav > li > ul > li a').length === 0) {
    $('#MailMenuSecondTier').hide();
  }
  if (jQuery(event.target).closest('.table>tbody>tr>td').length === 0) {
    $('#MailBodyList').hide();
  }
});

$("#MailBodyList .DropMenu").click(function(e) {
  e.stopPropagation();
  $('.ForThisSenderMore').show();
});
.custom-menu {
  display: none;
  z-index: 1000;
  position: absolute;
  margin: 0;
  padding: 0;
  list-style: none;
  overflow: hidden;
  border: 1px solid #CCC;
  white-space: nowrap;
  font-family: sans-serif;
  background: #FFF;
  color: #333;
  border-radius: 5px;
  font-size: 12px;
}
.custom-menu li {
  padding: 8px 12px;
  cursor: pointer;
}
.custom-menu li:hover {
  background-color: #DEF;
}
.custom-menu .divider {
  content: " ";
  height: 1px;
  margin: 4px 10px;
  background: #929292;
}
#MailBodyList.custom-menu li.Title {
  color: #929292;
}
#MailBodyList.custom-menu li.Title:hover {
  background: #FFF;
  cursor: default;
}
#MailBodyList.custom-menu li.ForThisSenderMore {
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<table class="table">
  <tbody>
    <tr>
      <td>Right click me</td>
    </tr>
  </tbody>
</table>

<ul class="custom-menu" id="MailMenuFirstTier">
  <li>New Sub-Folder</li>
  <li>Mark All As Read</li>
  <li>Empty Folder</li>
</ul>
<ul class="custom-menu" id="MailMenuSecondTier">
  <li>New Sub-Folder</li>
  <li>Rename</li>
  <li>Delete</li>
  <li>Mark All As Read</li>
  <li>Empty Folder</li>
</ul>
<ul class="custom-menu" id="MailBodyList">
  <li class="Title">For This Message</li>
  <li>Reply</li>
  <li>Reply All</li>
  <li>Forward</li>
  <div class="divider"></div>
  <li>Mark As unread</li>
  <li>Delete</li>
  <li>Archive</li>
  <li>Junk</li>
  <li>Move</li>
  <li>Create Rule</li>
  <li>Save To BananzaCloud</li>
  <li>View Message Source</li>
  <div class="divider"></div>
  <li class="DropMenu">For This Sender</li>
  <li class="ForThisSenderMore">Send Email</li>
  <li class="ForThisSenderMore">Find Email</li>
  <li class="ForThisSenderMore">Move All Emails From...</li>
  <li class="ForThisSenderMore">Delete All From...</li>
</ul>

Comments