Skip to content

Commit 24d9528

Browse files
author
Stuart McGrigor
committed
We need a context menu to play with our tree
1 parent 45d6f70 commit 24d9528

File tree

1 file changed

+173
-0
lines changed

1 file changed

+173
-0
lines changed

Diff for: context-menu.js

+173
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
(function ( angular ) {
2+
'use strict';
3+
4+
/* Figure out page (viewport) dimensions of current page, by
5+
* putting an empty DIV in the bottom right, and checking its offset.
6+
*/
7+
function getPageDimensions() {
8+
var bttmRight = document.createElement("div");
9+
bttmRight.setAttribute("style" , "visibility:hidden;position:fixed;bottom:0px;right:0px;");
10+
document.getElementsByTagName("body")[0].appendChild(bttmRight);
11+
var pageWidth = bttmRight.offsetLeft;
12+
var pageHeight = bttmRight.offsetTop;
13+
bttmRight.parentNode.removeChild(bttmRight);
14+
return { width:pageWidth, height:pageHeight };
15+
}
16+
17+
angular.module( 'contextMenu', [] )
18+
19+
.directive('contextMenuId', ['$document', function($document) {
20+
21+
return {
22+
restrict : 'A',
23+
scope : '@&',
24+
compile: function compile(tElement, tAttrs, transclude) {
25+
26+
return {
27+
post: function postLink(scope, iElement, iAttrs, controller) {
28+
29+
var ul = angular.element(document.querySelector('#' + iAttrs.contextMenuId));
30+
31+
ul.css({ 'display' : 'none'});
32+
33+
// right-click on context-menu will show the menu
34+
iElement.bind('contextmenu', function showContextMenu(event) {
35+
36+
// don't do the normal browser right-click context menu
37+
event.preventDefault();
38+
39+
// Organise to show off the menu (in roughly the right place)
40+
ul.css({
41+
visibility:"hidden",
42+
position: "fixed",
43+
display: "block",
44+
left: event.clientX + 'px',
45+
top: event.clientY + 'px'
46+
});
47+
48+
var ulDim = { height: ul.prop("clientHeight"),
49+
width: ul.prop("cientWidth")
50+
};
51+
52+
var pgDim = getPageDimensions();
53+
54+
// will ctxMenu fit on screen (height-wise) ?
55+
// TODO: figure out why we need the fudge-factor of 14
56+
var ulTop = event.clientY + ulDim.height <= pgDim.height - 14
57+
? event.clientY
58+
: pgDim.height - ulDim.height - 14;
59+
60+
// will ctxMenu fit on screen (width-wise) ?
61+
var ulLeft = event.clientX + ulDim.width <= pgDim.width - 2
62+
? event.clientX
63+
: pgDim.width - ulDim.width - 2;
64+
65+
// Ok, now show it off in the right place
66+
ul.css({
67+
visibility:"visible",
68+
position: "fixed",
69+
display: "block",
70+
left: ulLeft + 'px',
71+
top: ulTop + 'px'
72+
});
73+
74+
// setup a one-time click event on the document to hide the dropdown-menu
75+
$document.one('click', function hideContextMenu(event) {
76+
ul.css({
77+
'display' : 'none'
78+
});
79+
});
80+
});
81+
}
82+
};
83+
}
84+
};
85+
}])
86+
87+
.directive('contextSubmenuId', ['$document', function($document) {
88+
return {
89+
restrict : 'A',
90+
scope : '@&',
91+
compile: function compile(tElement, tAttrs, transclude) {
92+
return {
93+
post: function postLink(scope, iElement, iAttrs, controller) {
94+
95+
var ul = angular.element(document.querySelector('#' + iAttrs.contextSubmenuId));
96+
97+
ul.css({ 'display' : 'none'});
98+
99+
100+
iElement.bind('mouseover', function showSubContextMenu(event) {
101+
// use CSS to move and show the sub dropdown-menu
102+
if(ul.css("display") == 'none') {
103+
104+
// Organise to show off the sub-menu (in roughly the right place)
105+
ul.css({
106+
visibility:"hidden",
107+
position: "fixed",
108+
display: "block",
109+
left: event.clientX + 'px',
110+
top: event.clientY + 'px'
111+
});
112+
113+
var ulDim = { height: ul.prop("clientHeight"),
114+
width: ul.prop("clientWidth")
115+
};
116+
117+
var pgDim = getPageDimensions();
118+
119+
120+
// Will ctxSubMenu fit (height-wise) ?
121+
// TODO: figure out why we need the fudge-factor of 14
122+
var ulTop = event.clientY + ulDim.height <= pgDim.height - 14
123+
? event.clientY
124+
: pgDim.height - ulDim.height - 14;
125+
126+
// Will ctxSubMenu fit (on the right of parent menu) ?
127+
var ulLeft =
128+
(event.target.offsetParent.offsetLeft +
129+
event.target.clientWidth + ulDim.width < pgDim.width)
130+
? event.target.offsetParent.offsetLeft +
131+
event.target.clientWidth
132+
133+
: event.target.offsetParent.offsetLeft - ulDim.width;
134+
135+
// OK, now show it off in the right place
136+
ul.css({
137+
visibility:"visible",
138+
position: "fixed",
139+
display: "block",
140+
left: ulLeft + 'px',
141+
top: ulTop + 'px'
142+
});
143+
144+
// Each uncle/aunt menu item needs a mouseover event to make the subContext menu disappear
145+
angular.forEach(iElement[0].parentElement.parentElement.children, function(child, ndx) {
146+
if(child !== iElement[0].parentElement) {
147+
angular.element(child).one('mouseover', function(event) {
148+
if(ul.css("display") == 'block') {
149+
ul.css({
150+
'display' : 'none'
151+
});
152+
}
153+
});
154+
}
155+
});
156+
}
157+
158+
// setup a one-time click event on the document to hide the sub dropdown-menu
159+
$document.one('click', function hideContextMenu(event) {
160+
if(ul.css("display") == 'block') {
161+
ul.css({
162+
'display' : 'none'
163+
});
164+
}
165+
});
166+
});
167+
}
168+
};
169+
}
170+
};
171+
}]);
172+
173+
})( angular );

0 commit comments

Comments
 (0)