Skip to content
This repository has been archived by the owner on Nov 4, 2023. It is now read-only.

Commit

Permalink
Initial Commit
Browse files Browse the repository at this point in the history
Tested on Chrome, Internet Explorer, Microsoft Edge - known in issue in  Firefox explained in README.
  • Loading branch information
boardy committed Dec 3, 2017
1 parent bffad97 commit 4c7522e
Show file tree
Hide file tree
Showing 26 changed files with 21,409 additions and 0 deletions.
100 changes: 100 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# 3-dot Context Menu

Thanks for taking a look at our 3-dot context menu for web
development.

The 3-dot context menu allows a simple and lightweight
implementation for showing 3 vertical dots allowing the user
to click and show a menu.

## Requirements
Jquery is required and most modern browsers should support
the library. We've tested on the latest versions of Google
Chrome, Internet Explorer, Microsoft Edge. The only browser
that doesn't work is the latest Firefox Quantum (we'll get
into that in a bit).

## Implementing 3-dot Context Menu
Implementing the 3-dot context menu is as straight forward
as adding 1 javascript file and 1 css file with 1 line
of javascript code to implement the menu.

The 3-dot menu can be added inside <td> tags within
tables, within <p> tags and html heading tags such as
<h1>, <h2> etc. (up to <h5>).

In the head tag of your web page add the following

```
<script src="/3dot-context-menu/context-menu.js"></script>
<link href="/3dot-context-menu.css" rel="stylesheet">
```

Add the 3-dot menu to a component within your web page. Below
we're going to do it in a table, but &lt;p&gt; tags and
heading tags are supported.

Check the example project included for examples on how
to implement with each tag.

In a &lt;td&gt; tag add the class `context-menu` and a data
attribute called `date-container-id` with the id value of
the div containing your menu items. For example as below:

```
<td class="context-menu" data-container-id="my-context-menu-items"></td>
```

Then in your document ready function create a new instance
of `ContextMenu` and pass in two parameters. The first parameter
is the id of the div containing your menu items (same value as
in your `data-container-id`) and the second parameter is your
menu item click callback as follows:

```
$(document).ready(function(){
var varContextMenu = new ContextMenu("context-menu-items", function (menu_item, parent)
{
alert("Menu Item Clicked: " + menu_item.text() + "\nRecord ID: " + parent.attr("data-row-id"));
});
});
```

If you dynamically load data, such as in our example a table
make sure you call `destory()` on the contextMenuReturn object
before re-creating your view. If you don't do this, the click
handler for the menu might not fire, it might fire multiple
times depending on your browser.

# Known Issues
As far as we know there is only 1 known issue as mentioned
above with the latest Firebox browser.

For some reason in the context-menu.js it fails stating that
`this.contextMenu` is null. At the moment we've not found
what is causing this specific issue as it works with other
browsers but as soon as we find an answer we'll do an update.

Obviously though, if you know the issue, and fancy contributing
to this project then please feel free to do a pull request.

# Contributing to the Project
We'd love it if the open source community would contribute
to this project, fixing any issues, improving the code, adding
new features would all be very welcome.

My javascript knowledge is somewhat limited so I'm sure
there could be improvements made in places which we would of
course welcome.

Please make sure that if you make any changes to the javascript
or CSS that the minified versions are also updated.

The CSS can be minified by going to https://cssminifier.com/
and the javascript can be minified by going to https://jscompress.com/.

# Reporting bugs/feature requests/getting help
If you want to report an issue, have a feature request
or just want to get some help, you can either use the issue
tracker within GitHub or our support portal at https://support.boardiesitsolutions.com.

1 change: 1 addition & 0 deletions context-menu-min.css

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

1 change: 1 addition & 0 deletions context-menu-min.js

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

65 changes: 65 additions & 0 deletions context-menu.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/**
* @author Chris Board - Boardies IT Solutons
* @description Creates a 3-dot context menu on tables, <p> tags and heading tags (e.g. h1, h2 etc).
* @copyright (c) Boardies IT Solutions - December 2017
*/

.context-menu:after
{
content: '\2807';
font-size: 20px;
cursor: pointer;
cursor: hand;
pointer-events: all;
}

td.context-menu:after
{
float: right;
}

p.contextMenu:after > span
{
margin: 0 !important;
padding: 0 !important;
}

h1.context-menu:after,h2.context-menu:after,h3.context-menu:after,h4.context-menu:after,h5.context-menu:after
{
margin-left: 30px;
}

.context-menu-container
{
background-color: white;
z-index: 1000 !important;
border-radius: 5px;
position: absolute;
display: none;
border: solid thin black;
padding: 3px;
-webkit-box-shadow: 4px 4px 8px 0px rgba(0,0,0,0.18);
-moz-box-shadow: 4px 4px 8px 0px rgba(0,0,0,0.18);
box-shadow: 4px 4px 8px 0px rgba(0,0,0,0.18);
min-width: 90px;
}

.context-menu-container > ul
{
margin: 0;
padding: 0;
list-style-type: none;
}

.context-menu-container > ul > li
{
padding: 5px;
cursor: hand;
cursor: pointer;
border-radius: 5px;
}

.context-menu-container > ul > li:hover
{
background-color: #c4c4c4;
}
89 changes: 89 additions & 0 deletions context-menu.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/**
* @author Chris Board - Boardies IT Solutons
* @description Creates a 3-dot context menu on tables, <p> tags and heading tags (e.g. h1, h2 etc).
* @copyright (c) Boardies IT Solutions - December 2017
*/

$(document).mouseup(function (e) {
var div = $(".context-menu-container");
if (!div.is(e.target) && div.has(e.target).length === 0)
{
div.hide();
}
});

function ContextMenu(contextContainerID, menuItemClickCallback)
{

this.contextMenuContainer = $('.context-menu[data-container-id="'+contextContainerID+'"]');

this.contextMenuContainer.click(function(e){

var self = this;
var parent = $(this);

//var menuPos = $(this).offset();

//Show hide the context menu
var contextMenuID = "#" + $(this).attr("data-container-id");
this.contextMenu = $(contextMenuID);


//Use e.clientX get the cursor position and subtract the context menu width so that it appears on the left of
//the cursor, minus another 15 take the extra padding into account so the menu doesn't appear
//directly under the cursor
var menuPos = {left: e.clientX - this.contextMenu.width() - 15, top: e.clientY};

if (!isElementInViewport(this.contextMenu)) {
alert("View not visible");
var rightEdgePos = this.contextMenu.width() + this.contextMenu.offset().left;
var screenWidth = $(window).width();


var leftShiftOver = menuPos.left - (screenWidth - rightEdgePos);
var showPos = menuPos.left - leftShiftOver - 10; //Subtract an extra 10 so it has some margin space

alert("Right Edge Pos: " + rightEdgePos + "\n" + "Screen Width: " + screenWidth + "\nShow Pos: " + showPos);

this.contextMenu.css({top: menuPos.top, left: showPos, position: 'absolute'});
}
else
{
this.contextMenu.css({top: menuPos.top, left: menuPos.left, position: 'absolute'});
}

this.contextMenu.find("ul > li").click(function(){
menuItemClickCallback($(this), parent);
self.contextMenu.hide();

//Remove the click event otherwise a new one keep getting created, so an additional call event will be called
//each time the menu opens and closes
self.contextMenu.find("ul > li").unbind("click");
});
this.contextMenu.show();

});

this.destroy = function() {
console.log("destroying context menu");
console.log(this.contextMenuContainer);
this.contextMenuContainer.unbind("click");
};
}

function isElementInViewport (el) {

//special bonus for those using jQuery
if (typeof jQuery === "function" && el instanceof jQuery) {
el = el[0];
}

var rect = el.getBoundingClientRect();

return (
rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /*or $(window).height() */
rect.right <= (window.innerWidth || document.documentElement.clientWidth) /*or $(window).width() */
);
}
8 changes: 8 additions & 0 deletions example/.idea/ContextTest.iml

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

8 changes: 8 additions & 0 deletions example/.idea/modules.xml

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

Loading

0 comments on commit 4c7522e

Please sign in to comment.