mar10 / jquery-ui-contextmenu Goto Github PK
View Code? Open in Web Editor NEWjQuery plugin that turns a jQueryUI menu widget into a context menu.
License: Other
jQuery plugin that turns a jQueryUI menu widget into a context menu.
License: Other
See [Trigger popup] button on demo page
I'm completely baffled as to how right-clicking an element that matches the delegate selector on an initialized element ends up firing the 'contextmenu' event on the bound element... I've been reading this code for HOURS and I'm still not seeing anything like:
ui.target.on('right-click', opt.selector, function(){ this._tigger('contextmenu')});
or something along those lines.. I see no references to event.which() (for mouse button detection) etc.. how in the world are you doing this???
PLEASE HELP!
Is there a way I can destroy a context menu that I have created. I want not only the JQUERY object that I could get with "getMenu", but also the associated events to be removed.
reproduce:
http://wwwendt.de/tech/demo/jquery-contextmenu/demo/
Sample 1
bouble click on AAA
click on copy
result: select copy on
expected: select copy on AAA
We could allow to pass a callback function with an entry definition:
[{title: "Info...", action: function(event, ui){
alert("info about " + $(event.relatedTarget).text());
}
}
Chrome 27 on Ubuntu
On the demo, right click on one of the elements with the context menu attached. The jquery-ui-contextmenu appears. Right click on this menu, and the browsers context menu shows.
In my opinion, this shouldn't happen. Perhaps the contextmenu can catch the contextmenu (or the taphold) even and return false
I need the menu to be positioned relative to where the context menu event takes place. I can make this work by changing the
.position({
my: "left top",
at: "left bottom",
of: parentTarget,
collision: "fit"
})
in the _openMenu function to look like the following:
.position({
my: "left top",
at: "left+" + event.offsetX + " top+" + event.offsetY,
of: parentTarget,
collision: "fit"
})
Never the less, I believe it would be better to allow individuals to select where they want the menu to appear. I can accomplish this by creating a new callback say repositionMenu that returns the relative position that .position will use, or have the menu passed in to the repositionMenu callback and have that method re-position the menu. You can either create a default repositionMenu that default to 'left top' to 'left botton' or some other idea. NOTE: the callback does not have to be an event callback, but it can be if you prefer that.
Let me know if I can help any on this project or if you think I should branch and go off on my own.
Allow taphold to trigger the menu
http://stackoverflow.com/questions/2625210/long-press-in-javascript
I don't know even if this is an issue.
I'm trying to do 2 different context menus, one that applies to a div element and the other, to it's children elements (other divs).
What is happening is that when i click the right button on a nested div, both menu ( assigned to parent and the one assigned to it's child ) shows up, one overlapping the other.
I don't know if i'm configuring the menus the right way, so it's more a doubt than an issue.
Thanks in advance.
I'm having this behavior in Chrome 22 and Firefox 17
The setEntry command should take parameter that looks more like the menu option literal. Right now the command requires a parameter to identify the menu option, and then an object that somewhat resembles the menu option.
$(...).contextmenu('setEntry', 'paste', {title: 'Paste link'});
Why not put the identifier in the menu option supplement? That way it would look more like the menu option literal provided in the menu array.
$(...).contextmenu('setEntry', {cmd: 'paste', title: 'Paste link'});
If the value for cmd doesn't match anything in the menu array, it could add a new menu option.
While we're at it, why call the menu option identifier cmd? The value of cmd isn't a command, it's a string ('paste'). It should be called something that reflects its purpose as a unique identifier. How about name or id?
See here:
https://github.com/kamens/jQuery-menu-aim
Best way would be to extend the original jQuery UI Menu however.
Thanks for this good plugin.
This is just a proposal to add an option that let's you select a right or left click to fire the context menu.
feel free to leave any ideas/comments.
I made a few changes to your code to allow us to change the menu option depending on the element clicked.
-114 _getMenu: function(){
+114 _getMenu: function(event){
-118 $menu = $menu();
+118 $menu = $menu(event);
-130 $menu = this._getMenu(),
+130 $menu = this._getMenu(event),
If you liked it, you can change the main code.
Thanks
Sometimes the event order seems to be unexpected:
https://saucelabs.com/tests/3d57ed01ff84404eae3a5ca40637158a
Currently only the framework and a dummy test is in place.
Old IE versions do not support creating a style tag the standard way.
This article suggests a workaround:
http://webbugtrack.blogspot.ro/2009/01/bug-143-createtextnode-doesnt-work-on.html
I would like to set text in bold for a menu item (this is the "default action" when the user double click on the object the menu is bound).
I tried to fork and grunt but it got way more complicated than I thought it would.
Anyway I am missing the possibility to pass the position parameter for the menu widget.
Not the contextmenu position parameter but the menu widgets position parameter, it tells the menu widget where to position submenus.
Was thinking a parameter called subPosition, defaults to menu's default position:
{ my: "left top", at: "right top" }
This is quite important to have cause of the collision parameter:
{ my: "left top", at: "right top", collision: "fit"}
Or maybe just default to { my: "left top", at: "right top", collision: "fit"}.
Thanks
https://github.com/aduth/grunt-jquerymanifest
And Set the Version property in the .js file from the Manifest value:
https://github.com/outaTiME/grunt-replace
A common use case requires that single menu entries are added, removed or disabled, depending on external conditions.
For example a Paste entry is disabled while the clipboard is empty.
Nice project, thanks. I think I may end up using this.
I have a question/feature request.
Say I have a ul with list of items which I wish to add a context menu to. Seems straight forward, but the list items are representations of different types. One item maybe an image, another maybe a video, another might be a page of text. Each different type of item will have standard actions (cut, copy, paste, rename, etc) but will also have custom actions. For a video you may have trim, volume. For image you might have resize, rotate, crop. And for a text item you might have edit, print.
Is there away of doing this with out creating seperate menus (and thus duplicating the standard items)?
If not, could a context option be added? So on initialisation, you would define the standard items, and then define a 'context' for each different type. The context menu could then work out which context menu to show by reading a tag on the li (maybe something like data-type)?
The setEntry functionality can be used with a string or an object input.
$("#details").contextmenu("setEntry", "opt1", {title: titleText});
$("#details").contextmenu("setEntry", "opt2", titleText);
This is the first right click. Things seem to be working as expected.
The second right click shows that there is something wrong. The title modification from the first right click is present in option 1.
Here is a working example:
<link href="js/lib/jquery-ui-1.10.3/css/smoothness/jquery-ui-1.10.3.custom.css" type="text/css" rel="stylesheet" />
<script src="js/lib/jquery-1.8.2.min.js" type="text/javascript"></script>
<script src="js/lib/jquery-ui-1.10.3/js/jquery-ui-1.10.3.custom.js" type="text/javascript"></script>
<script src="js/lib/jquery.ui-contextmenu.js" type="text/javascript"></script>
<style type="text/css">
.hasmenu {
border: 1px solid #008;
margin: 3px;
padding: 5px;
width: 30px;
}
.ui-widget{
font-size: .8em;
}
table, td {
border: 1px solid dimgray;
}
</style>
<script type="text/javascript">
$(document).ready(function () {
function action (event, ui) {
console.log(ui.target);
};
$("#details").contextmenu({
delegate: ".hasmenu",
menu: [
{title: "Option 1 title", cmd: 'opt1', action: action},
{title: "Option 2 title", cmd: 'opt2', action: action}
],
beforeOpen: function(event, ui) {
var titleText = 'record ' + ui.target.parent().attr('record');
$("#details").contextmenu("setEntry", "opt1", {title: titleText});
$("#details").contextmenu("setEntry", "opt2", titleText);
}
});
});
</script>
<table id="details" class="table">
<thead>
<tr>
<th>Id</th>
<th>File Name</th>
<tr />
</thead>
<tbody>
<tr record="1" class="hasmenu">
<td>1</td>
<td>Record 1</td>
</tr>
<tr record="2" class="hasmenu">
<td>2</td>
<td>Record 2</td>
</tr>
</tbody>
</table>
I am using the contextMenu to allow the deletion of elements in a list, when the "Delete" option is selected, the Select event fires, inside this event I am removing the "ui.target" element by using ui.target.remove();
When the target has been removed this error is thrown by jQuery UI.
Is there some way for me to handle this? I've tried handling the "close" event but without success.
This currently only works, if the initial menu and the new menu were created using a definition array.
Should also work for <ul>
style.
option.menu does no longer need to accept a function anymore.
See here for a sample http://api.jqueryui.com/tabs/#option-show
The user should be able to issue an ajax request when a menu is opened, in order modify new menu structure.
In this case, we could return a $.promise() or a callback from beforeOpen
.
The menu would wait for promise.done() or the callback before rendering.
Or we open the menu as before, and then the user can do some
'show throbber - load ajax - modify menu'
Plugin not working on XHTML page. Same page with HTML content type works. In console:
Uncaught SyntaxError: An invalid or illegal string was specified. jquery.js:6469 jQuery.extend.buildFragment jquery.js:6469 jQuery.extend.parseHTML jquery.js:531 jQuery.fn.jQuery.init jquery.js:149 jQuery jquery.js:62 $.widget._create jquery.ui-contextmenu.js:56 (anonymous function) jquery-ui.js:401 $.Widget._createWidget jquery-ui.js:560 $.(anonymous function).(anonymous function) jquery-ui.js:362 (anonymous function) jquery-ui.js:507 jQuery.extend.each jquery.js:648 jQuery.fn.jQuery.each jquery.js:270 $.fn.(anonymous function) jquery-ui.js:502 (anonymous function) index.xhtml:251 fire jquery.js:1037 self.fireWith jquery.js:1148 jQuery.extend.ready jquery.js:433 completed jquery.js:103
e.g.
ryrych/rcarousel#16
or
When you define a widget with the
$.widget("namespace.widgetname") syntax, the widget factory instantiates the widget "class" inside $ [ namespace ]. All jQuery UI widgets exist in the $.ui namespace, which is reserved for official widgets, so make sure you change this to something unique. Namespaces are used internally for organizational purposes; they do not allow you to create multiple widgets with the same name.
I've read the documentation and I can't seem to find a function which will return the Id of the element which has called the menu.
Edit: The reason why I am even mentioning is that a decent amount of people seem to be looking for this when choosing what context menu plug-in to use.
When right-clicking a div-tag the contained text sometimes is marked as selected by the browser. (Observed with Safari on a MacBook, using two-finger click on the trackpad).
An option disableSelection: true
could help to prevent this.
jQuery UI implemented it this way (note: this function is deprecated since 1.9):
$.support.selectstart = "onselectstart" in document.createElement( "div" );
$.fn.extend({
disableSelection: function() {
return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
".ui-disableSelection", function( event ) {
event.preventDefault();
});
},
enableSelection: function() {
return this.unbind( ".ui-disableSelection" );
},
I have a div.
I want my contextmenu to open inside div.
I do NOT want contextmenu to open on right-click in div.
I want contextmenu to be able to be manually triggered through events in other areas of my code.
If can manually use the command that opens on a target, but it must be inside a valid delegate property target. But I don't want my menu to open on user's right clicks. Is the only way to do this returning false on beforeOpen? I would prefer to save processing power and the uncessary events that occur to go through creating a new context menu that I don't want, etc.
Hi,
Great tools you have made.
I have encountered an issue using the contextmenu lib. It seldoms happen but there is an overlapping between the 2 menu levels - see the screenshot attached.
Here is the code I have used :
Contextmenu creation :
$("#html-container").contextmenu({
delegate: ".hasContextMenu",
menu: "#options",
show: { effect: "blind", duration: 100 },
position: function (event, ui) {
return { my: "left top", at: "left", of: event, collision: "flipfit", within: $("#html-viewport") }
},
preventSelect: true,
blur: function (event, ui) {
if (event.toElement && event.toElement.id == 'canvas')
this.close();
},
beforeOpen: function (event, ui) {
if (!enableContextMenu) {
enableContextMenu = options.EnableContextMenu;
return false;
} else {
if (!DirectionalLightCastShadow && !SpotLightCastShadow)
$("#html-container").contextmenu("showEntry", "shadow-control-element", false);
else
$("#html-container").contextmenu("showEntry", "shadow-control-element", true);
}
}
});
Menu code :
"<ul id='options' style='display: none;'>" +
"<li><a href='#'><span class='ui-icon ui-icon-views'></span>" + options.Resources['3DWebGL.ContextMenu.ViewModes'] + "</a>" +
"<ul>" +
"<li class='view-isometric-context-menu view-isometric ui-view-isometric'><a href='javascript:;'><span class='ui-icon ui-icon-isometric'></span>" + options.Resources['3DWebGL.ContextMenu.IsometricView'] + "</a></li>" +
"<li class='view-front-context-menu view-front ui-view-front'><a href='javascript:;'><span class='ui-icon ui-icon-front'></span>" + options.Resources['3DWebGL.ContextMenu.FrontView'] + "</a></li>" +
"<li class='view-back-context-menu view-back ui-view-back'><a href='javascript:;'><span class='ui-icon ui-icon-back'></span>" + options.Resources['3DWebGL.ContextMenu.BackView'] + "</a></li>" +
"<li class='view-left-context-menu view-left ui-view-left'><a href='javascript:;'><span class='ui-icon ui-icon-left'></span>" + options.Resources['3DWebGL.ContextMenu.LeftView'] + "</a></li>" +
"<li class='view-right-context-menu view-right ui-view-right'><a href='javascript:;'><span class='ui-icon ui-icon-right'></span>" + options.Resources['3DWebGL.ContextMenu.RightView'] + "</a></li>" +
"<li class='view-top-context-menu view-top ui-view-top'><a href='javascript:;'><span class='ui-icon ui-icon-top'></span>" + options.Resources['3DWebGL.ContextMenu.TopView'] + "</a></li>" +
"<li class='view-bottom-context-menu view-bottom ui-view-bottom'><a href='javascript:;'><span class='ui-icon ui-icon-bottom'></span>" + options.Resources['3DWebGL.ContextMenu.BottomView'] + "</a></li>" +
"</ul>" +
"</li>" +
"<li>----</li>" +
"<li><a href='#'><span class='ui-icon ui-icon-render'></span>" + options.Resources['3DWebGL.ContextMenu.RenderModes'] + "</a>" +
"<ul>" +
"<li class='render-shaded-context-menu render-shaded'><a href='javascript:;'><span/>" + options.Resources['3DWebGL.ContextMenu.Shaded'] + "</a></li>" +
"<li class='render-wireframe-context-menu render-wireframe'><a href='javascript:;'><span/>" + options.Resources['3DWebGL.ContextMenu.Wireframe'] + "</a></li>" +
"<li class='render-shaded-wireframe-context-menu render-shaded-wireframe'><a href='javascript:;'><span/>" + options.Resources['3DWebGL.ContextMenu.ShadedWireframe'] + "</a></li>" +
"<li class='render-transparent-context-menu render-transparent'><a href='javascript:;'><span/>" + options.Resources['3DWebGL.ContextMenu.Transparent'] + "</a></li>" +
"<li class='render-transparent-wireframe-context-menu render-transparent-wireframe'><a href='javascript:;'><span/>" + options.Resources['3DWebGL.ContextMenu.TransparentWireframe'] + "</a></li>" +
"</ul>" +
"</li>" +
"<li>----</li>" +
"<li><a href='#'><span class='ui-icon ui-icon-selection'></span>" + options.Resources['3DWebGL.ContextMenu.SelectionModes'] + "</a>" +
"<ul>" +
"<li class='mode-rotation-context-menu mode-rotation ui-status'><a href='#'><span class='ui-icon ui-icon-rotation'></span>" + options.Resources['3DWebGL.ContextMenu.RotationMode'] + "</a></li>" +
"<li class='mode-pan-context-menu mode-pan ui-status'><a href='#'><span class='ui-icon ui-icon-pan'></span>" + options.Resources['3DWebGL.ContextMenu.PanMode'] + "</a></li>" +
"<li class='mode-zoom-context-menu mode-zoom ui-status'><a href='#'><span class='ui-icon ui-icon-zoom'></span>" + options.Resources['3DWebGL.ContextMenu.ZoomMode'] + "</a></li>" +
"<li class='mode-zoom-window-context-menu mode-zoom-window ui-status'><a href='#'><span class='ui-icon ui-icon-zoom-window'></span>" + options.Resources['3DWebGL.ContextMenu.ZoomWindowMode'] + "</a></li>" +
"<li class='mode-interactive-context-menu mode-interactive ui-status'><a href='#'><span class='ui-icon ui-icon-interactive'></span>" + options.Resources['3DWebGL.ContextMenu.InteractiveMode'] + "</a></li>" +
"</ul>" +
"</li>" +
"<li>----</li>" +
"<li><a class='smooth-transition-control' href='javascript:;'><span/>" + options.Resources['3DWebGL.ContextMenu.SmoothTransition'] + "</a></li>" +
"<li><a class='shadow-control' href='#shadow-control-element'><span/>" + options.Resources['3DWebGL.ContextMenu.Shadow'] + "</a></li>" +
"</ul>"
Can you help me?
Thanks for help !
Updating a menu entry without a title attribute throws an error.
tableBody.contextmenu("setEntry", "update", {uiIcon: 'ui-icon-closethick'});
Results in:
$.extend($.moogle.contextmenu, {
/** Convert a menu description into a into a <li> content. */
createEntryMarkup: function(entry, $parentLi){
var $a = null;
if(entry.title.match(/^---/)){
// Uncaught TypeError: Cannot call method 'match' of undefined
You should be able to update any menu object attribute besides "cmd" without supplying a title attribute.
in the current demo
how possible is it to replace the jquerry ui icons with something like fontawesome's icon images?
(Currently storing "#" + CMD in the menus href
attribute.)
This would allow to freely define href ( #34 )
I have an existing set of elements with menus something like this:
blah blahAll works great.
Sometimes I need to add additional items, so I create a new with javascript and add it to the row above. This all works fine. I take the new JS cell object and do a
newTableCell.addClass('hasMenu');
This menu does not come up for this cell.
I tried things like:
$(".hasmenu").contextmenu("refresh");
$(".hasmenu").menu("refresh");
$(newTableCell).contextmenu("refresh");
$(newTableCell.menu("refresh");
$(document).contextmenu("refresh");
$(document.menu("refresh");
No luck. Any idea what I might be doing wrong? I'm assuming you can do this...
The menu
option could optionally accept an array of menu entries, e.g.
[{title: "Edit", href; "#edit", uiIcon: "ui-icon-pencil"},
{title: "Delete", href; "#delete", disabled: true},
{title: "----"},
{title: "More", children: [
{title: "Sub-item1", href; "#sub1"}
]},
]
This information could then be used to generate the <ul><li>
markup on the fly.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.