Custom right click menu only show on children of div - javascript

http://jsfiddle.net/TnbYm/
I'm trying to get my right click menu to only show on children of #canvas. I also want to have it remove when a child is not clicked, but one of the problems are because document is being called as the container document closes it before the action is called.
If anyone can help me with this it'll be greatly appreciated.
if ( $("#tm").prop('checked') === true ) {
// Trigger action when the contexmenu is about to be shown
$("#canvas").find("*").bind("contextmenu", function (event) {
// Avoid the real one
event.preventDefault();
$("#custom-menu").hide(100);
// Show contextmenu
if ($("#showcustom-menu").show() === true) {
$("#custom-menu").hide(100).
// In the right position (the mouse)
css({
top: event.pageY + "px",
left: event.pageX + "px"
});
} else {
$("#custom-menu").show(100).
// In the right position (the mouse)
css({
top: event.pageY + "px",
left: event.pageX + "px"
});
}
});
// If the document is clicked somewhere
$(document).bind("mousedown", function () {
$("#custom-menu").hide(100);
});
} else {
$(document).unbind("contextmenu");
}
$("#tm").on('change', function() {
if ( $(this).prop('checked') === true ) {
// Trigger action when the contexmenu is about to be shown
$("#canvas").find("*").bind("contextmenu", function (event) {
// Avoid the real one
event.preventDefault();
$("#custom-menu").hide(100);
// Show contextmenu
if ($("#custom-menu").show() === true) {
$("#custom-menu").hide(100).
// In the right position (the mouse)
css({
top: event.pageY + "px",
left: event.pageX + "px"
});
} else {
$("#custom-menu").show(100).
// In the right position (the mouse)
css({
top: event.pageY + "px",
left: event.pageX + "px"
});
}
});
// If the document is clicked somewhere
$(document).bind("mousedown", function () {
$("#custom-menu").hide(100);
});
} else {
$(document).unbind("contextmenu");
}
});
// Menu's button actions
$("#custom-menu > button").click(function() {
alert($(this).text() + "was clicked");
});
$("#custom-menu > button#duplicate").click(function() {
// $('#canvas').append($(this).clone());
$("#custom-menu").hide(100);
});
$("#custom-menu > button#remove").click(function() {
// $(this).remove();
$("#custom-menu").hide(100);
});
$("#custom-menu").find("button#deselect, button#close").click(function() {
$("#custom-menu").hide(100);
});

You can use CSS selectors for that:
$(document).on('contextmenu', function (e) {
if (e.target.matches('#canvas *'))
alert('Contexted!');
else
alert('Not contexted!');
});
Element.matches
Fiddle

Hi i have updated the jsfiddle provided by you please go through that..
its working fine and you can add code into the click method according to your need.
Link for jsfiddle:- http://jsfiddle.net/TnbYm/14/

Related

Is there a way to get the mouse coordinates with respect to page on mouseOver of a point in Highcharts?

I am trying to have a highchart spline chart with tooltip positioned to the right corner and have another tooltip on mouseover specific points. So basically I would like to show Two tooltips for some points. So far i was able to do that only on click event where we the event information with mouse coordinates with respect to page. Is there a way we can show two tooltips for same point? I want one tooltip to be positioned at the right corner and the other one next to the point as shown in the below JSfiifle.
"point": {
"events": {
"mouseOver": function(e) {
var selectedPoints = $('#' + this.series.chart.renderTo.id).highcharts().getSelectedPoints();
if (selectedPoints.length) {
selectedPoints[0].select();
}
if (e.target.marker && !e.target.marker.radius) {
return;
}
},
"mouseOut": function(e) {
util.hideBandInsightsPopup();
},
"click": function(e) {
if (e.point && e.point.marker && !e.point.marker.radius) {
return;
}
$("#factor-popup-content").html("my popup content");
var yPixel = e.pageY + 5;
var currentPointHeight = yPixel + $("#factor-popup").height();
if ($("#factor-popup").height() < 300 && currentPointHeight > $(window).height()) {
var adjustHeight = currentPointHeight - $(window).height() + 30;
yPixel = yPixel - adjustHeight;
}
$("#factor-popup").css({
'position': 'fixed',
'top': (yPixel) + 'px',
'left': (e.pageX) + 5 + 'px'
}).show();
}
}
}
Here is the Jsfiddle http://jsfiddle.net/zLpakfj2/4/
The original event is not passed to the mouseOver event, but you can add it for example to a point in this way:
(function(H) {
H.wrap(
H.Pointer.prototype,
'getHoverData',
function(
proceed,
existingHoverPoint,
existingHoverSeries,
series, isDirectTouch,
shared,
e
) {
var result = proceed.apply(this, Array.prototype.slice.call(arguments, 1));
if (result.hoverPoint) {
result.hoverPoint.originalEvent = e;
}
return result;
});
}(Highcharts));
Live demo: http://jsfiddle.net/BlackLabel/y18h30t4/
Docs: https://www.highcharts.com/docs/extending-highcharts/extending-highcharts

Jquery stop event for context menu

I'm making a context menu, but there a problem for my context menu, when I right click I wish the context menu stop on the position. I have tried using .stop() but it doesn't work.
This is the JS Fiddle
JQUERY
$(".menu").hide();
$(document).on("contextmenu", ".element", function (e) {
$(".menu").fadeIn();
return false;
});
$(document).mouseup(function (e) {
$(".menu").fadeOut(300);
});
$(document).bind('mousemove', function(e){
$('.menu').css({
left: e.pageX + 20,
top: e.pageY
});
$(".menu").stop();
});
Here's one approach where you check if the menu is visible and don't move it if it is.
var $menu = $(".menu").hide();
$(document).on("contextmenu", ".element", function (e) {
$menu.fadeIn();
return false;
});
$(document).mouseup(function (e) {
$menu.fadeOut(300);
});
$(document).bind('mousemove', function (e) {
if ($menu.is(':visible')) {
return;
}
$menu.css({
left: e.pageX + 20,
top: e.pageY
});
});
DEMO
Alternatively you can use the contextmenu event to set menu position without using mousemove.
$(document).on("contextmenu", ".element", function (e) {
$menu.css({
left: e.pageX + 20,
top: e.pageY
}).fadeIn();
return false;
});
DEMO 2

Convert click code to hover code

How can I change the following menu code to open/close when the mouse hovers, instead of when it is clicked on?
var w = 0;
$('.slide').children().each(function () {
w += $(this).outerWidth();
});
$('.outer').width(w + 5);
$('.wrap').width(w);
$('.slide').css('left', w);
$('.open').toggle(function () {
$('.slide').stop().animate({
left: 0
});
$(this).html('close');
}, function () {
$('.slide').stop().animate({
left: w
});
$(this).html('open');
});
Please check this Demo
In Fiddle, you can see the animation works on click. I need to make it work on hover. Can you help with this ?
Use .hover() api
Try this
$('.open').hover(function () {
instead of
$('.open').toggle(function () {
Just
$('.open').toggle(function() {
$('.slide').stop().animate({
left: 0
});
$(this).html('close');
}
in this part just replace toggle with hover
Try using $('.wrap').hover. If $('.open').hover, you will not able to click the nav items.
Also, you can create another wrapper to just wrap div.outer and a.open only
$('.wrap').hover(function() {
$('.slide').stop().animate({
left : 0
});
//this is the .wrap right now
$(this).find('a.open').html('close');
}, function() {
$('.slide').stop().animate({
left : w
});
//this is the .wrap right now
$(this).find('a.open').html('open');
});
http://jsfiddle.net/rooseve/42sWB/2/
$('.open').on('mouseenter mouseleave', function(e) {
if(e.type === 'mouseleave') {
$('.slide').stop().animate({
left: w
});
$(this).html('open');
} else {
$('.slide').stop().animate({
left: 0
});
$(this).html('close');
}
});
var w = 0;
var isVisible = false;
$('.slide').children().each(function() {
w += $(this).outerWidth();
});
$('.outer').width(w+5);
$('.wrap').width(w);
$('.slide').css('left', w);
$('.open').on("mouseover", function() {
if(isVisible == false) {
$('.slide').stop().animate({
left: 0
});
$(this).html('close');
isVisible = true;
}
else {
$('.slide').stop().animate({
left: w
});
$(this).html('open');
isVisible = false;
}
});
Firstly, when you hover the element - the div will be visible, until you hover the element for the second time.
Demo: http://jsfiddle.net/42sWB/3/

Unable to drop an element on mouseup event

Here is the jQuery code that I have written to drag multiple items at a time. It is draggable now but not droppable.
here is the code
$(document).on('click', function (e) {
var target = e.target;
if (!$(target).hasClass('a')) $('.selected').removeClass('selected');
});
$(document).delegate('.a', 'dblclick', function (e) {
$(this).addClass('selected');
});
$(document).delegate('.selected', 'mousedown', function (e) {
var div = $('<div></div>');
$('.selected').each(function () {
div.append($(this).clone());
});
div.prop('id', 'currentDrag');
$('#currentDrag').css({
left: e.pageX + "px",
top: e.pageY + "px"
});
$('body').append(div);
});
$(document).on('mouseup', function (e) {
var tgt = e.target;
var mPos = {
x: e.pageX,
y: e.pageY
};
$('.drop').each(function () {
var pos = $(this).offset(),
twt = $(this).width(),
tht = $(this).height();
});
if((mPos.x > pos.left) && (mPos.x < (pos.left + twt)) && (mPos.y > targPos.top) && (mPos.y < (pos.top + tht))) {
$(this).append($('#currentDrag').html());
}
$('.drop .selected').removeClass('selected');
$('#currentDrag').remove();
});
$('.drop').on('mouseup', function (e) {
$(tgt).append($('#currentDrag').html());
$('.drop .selected').removeClass('selected');
$('#currentDrag').remove();
});
$(document).on('mousemove', function (e) {
$('#currentDrag').css({
left: e.pageX + "px",
top: e.pageY + "px"
});
});
What is the pronblem with my code and how can I achieve this. here is the fiddle http://jsfiddle.net/mDewr/27/
I would really recommend trying to find a way to make the jQuery UI draggable and droppable libraries work for you. Then the question becomes,
similar to this one: How do I drag multiple elements with JavaScript or jQuery?.
Here's how we can apply one of the answers from that question to your problem. I'm using the jQuery UI multiple draggable plugin, the entire script of which can be found here: jquery.ui.multidraggable-1.8.8.js.
First let's simplify your HTML. By putting our draggable and dropable divs inside of elements, we don't have to apply redundant stylings to each one. Instead we can use the containing element to style
HTML
<div id="parent">
<div id="dragTargets">
<div>123</div>
<div>456</div>
<div>789</div>
</div>
<div id='dropTargets'>
<div></div>
<div></div>
</div>
</div>
Using the plugin we can call multidraggable on each of the drag divs. And droppable anywhere they can be dropped
JavaScript
$("#dragTargets div").multidraggable();
$("#dropTargets div").droppable();
Customize
We can control the appearance with styling. As an example, we'll make anything that can receive drops yellow, anything you're about to drop as red, and anything that has received an element green.
Here's some styling as an example in CSS
.ui-state-highlight { background: green; }
.ui-state-active { background: yellow; }
.ui-state-hover { background: red; }
And we'll control when these classes are applied with JavaScript:
$("#dropTargets div").droppable({
activeClass: "ui-state-active",
hoverClass: "ui-state-hover",
drop: function () {
$(this).addClass("ui-state-highlight")
}
});
Multi-Draggable
You should style the elements that are currently selected. The script will apply the class ui-multidraggable to all the currently selected elements. The following CSS will make it apparent to the user that their choice is selected.
.ui-multidraggable {
background: tan;
}
Check out this demo. Just hold down ctrl to select more than one of the divs and then drag all of them at once.
jsFiddle
There are few errors in you code. You can check errors on browser console.
To check elements over droppable area, you should check the drop area in the each loop, rather than after each loop. When moving mouse, you should better turn off selection to avoid selected text flashing
$(document).on('click', '.a', function (e) {
$(this).removeClass('selected');
});
$(document).on('dblclick', '.a', function (e) {
$(this).toggleClass('selected');
});
$(document).on('mousedown', '.selected', function (e) {
var dragMode = true;
var div = $('<div></div>');
$('.selected').each(function () {
div.append($(this).clone());
});
div.prop('id', 'currentDrag');
$('#currentDrag').css({
left: e.pageX + "px",
top: e.pageY + "px"
});
$('body').append(div);
//disable selection on dropping start
disableSelection();
$(document).on('mousemove.drop', function(e){
onDragging(e, dragMode);
});
$(document).on('mouseup.drop', function(e){
onDragEnd(e, dragMode);
});
});
function onDragEnd(e, dragMode){
if(!dragMode)
return;
var tgt = e.target;
var mPos = {
x: e.pageX,
y: e.pageY
};
$('.drop').each(function () {
var pos = $(this).position(),
twt = $(this).width(),
tht = $(this).height();
if((mPos.x > pos.left) &&
(mPos.x < (pos.left + twt)) &&
(mPos.y > pos.top) &&
(mPos.y < (pos.top + tht))) {
$(this).append($('#currentDrag').html());
}
});
$('.drop .selected').removeClass('selected');
$('#currentDrag').remove();
$('.onDrop').removeClass('onDrop');
//remove listener on docuemnt when drop end
$(document).off('mousemove.drop');
$(document).off('mouseup.drop');
//enable selection
enableSelection();
}
function onDragging(e, dragMode){
if(!dragMode)
return;
var p = $('body').offset();
var mPos = {
x: e.pageX,
y: e.pageY
};
$('#currentDrag').css({
left: mPos.x,
top: mPos.y
});
$('.drop').each(function () {
var pos = $(this).position(),
twt = $(this).width(),
tht = $(this).height();
$(this).toggleClass("onDrop",
(mPos.x > pos.left)
&& (mPos.x < (pos.left + twt))
&& (mPos.y > pos.top)
&& (mPos.y < (pos.top + tht))
);
});
}
function disableSelection(){
$(document).on("selectstart", function(){ return false; });
//firefox
$("body").css("-moz-user-select", "none");
}
function enableSelection(){
$(document).off("selectstart");
//firefox
$("body").css("-moz-user-select", "");
}
I updated your code: http://jsfiddle.net/mDewr/46/, may can help you.
There were several errors, which I'll not list now, but you can compare the old version with the new one.
$(document).on('dblclick', '.a', function (e) {
$(this).toggleClass('selected');
});
$(document).on('mousedown', '.selected', function (e) {
var div = $('<div id="currentDrag"></div>');
$('.selected').each(function () {
div.append($(this).clone(true));
});
var p = $('body').offset();
var l = e.pageX - p.left;
var t = e.pageY - p.top;
console.log(l, ', ', t);
$('body').append(div);
$('#currentDrag').css({
left: l,
top: t
});
});
$(document).on('mouseup', '.selected', function (e) {
$('.d').each(function(index, item){
var $i = $(item);
if (e.pageX >= $i.offset().left &&
e.pageX <= $i.offset().left + $i.width() &&
e.pageY >= $i.offset().top &&
e.pageY <= $i.offset().top + $i.height()) {
console.log('Dropped');
var $cl = $('#currentDrag').find('>*').clone(true);
$i.append($cl);
}
});
$('.selected').removeClass('selected');
$('#currentDrag').remove();
});
$(document).on('mousemove', function (e) {
var p = $('body').offset();
$('#currentDrag').css({
left: e.pageX - p.left,
top: e.pageY - p.top
});
});
http://jsfiddle.net/mDewr/43/
Everything should work perfectly in this version (this is an update).
PS: I've changed to 1.7+ jQuery, but you can easily change it back to <1.7. Also you don't need custom attributes, use css classes instead.

Positioning Context Menu

I'm trying to position a custom context menu with jQuery.
The first time it appears at the right position (mouse coordinates), but then the current position is being summed up with the new position, so that the menu disappears from the screen.
Here is the JavaScript:
<script>
$(function(){
$('#box').hide();
$(document).bind("contextmenu", function(e) {
$("#box").offset({left:e.pageX, top:e.pageY});
$('#box').show();
e.preventDefault();
});
$(document).bind("click", function(e) {
$('#box').hide();
});
$('#box').bind("click", function(e) {
$('#box').hide();
});
});
</script>
Try position: fixed; with position of context menu changes based on following condition -
var windowHeight = $(window).height()/2;
var windowWidth = $(window).width()/2;
if(e.clientY > windowHeight && e.clientX <= windowWidth) {
$("#contextMenuContainer").css("left", e.clientX);
$("#contextMenuContainer").css("bottom", $(window).height()-e.clientY);
$("#contextMenuContainer").css("right", "auto");
$("#contextMenuContainer").css("top", "auto");
} else if(e.clientY > windowHeight && e.clientX > windowWidth) {
$("#contextMenuContainer").css("right", $(window).width()-e.clientX);
$("#contextMenuContainer").css("bottom", $(window).height()-e.clientY);
$("#contextMenuContainer").css("left", "auto");
$("#contextMenuContainer").css("top", "auto");
} else if(e.clientY <= windowHeight && e.clientX <= windowWidth) {
$("#contextMenuContainer").css("left", e.clientX);
$("#contextMenuContainer").css("top", e.clientY);
$("#contextMenuContainer").css("right", "auto");
$("#contextMenuContainer").css("bottom", "auto");
} else {
$("#contextMenuContainer").css("right", $(window).width()-e.clientX);
$("#contextMenuContainer").css("top", e.clientY);
$("#contextMenuContainer").css("left", "auto");
$("#contextMenuContainer").css("bottom", "auto");
}
http://jsfiddle.net/AkshayBandivadekar/zakn7Lwb/14/
Don't use offset method, try css instead, positioning context menu absolutely:
$("#box").css({left:e.pageX, top:e.pageY});
CSS:
#box {
...
position: absolute;
}
http://jsfiddle.net/smxLk/
The problem is that when you right click then left click elsewhere and then right click again, the position is incorrect.
The root of the problem is that you set the offset before showing the element. It appears that it confuses jQuery if the element is set to display:none and then its offset is changed.
To fix the problem you need to switch the show and the offset lines in your code:
$(document).bind("contextmenu", function(e) {
$("#box").offset({left:e.pageX, top:e.pageY});
$('#box').show();
e.preventDefault();
});
becomes
$(document).bind("contextmenu", function(e) {
$('#box').show();
$("#box").offset({left:e.pageX, top:e.pageY});
e.preventDefault();
});
Demo and
Source

Categories