JointJS - Mouse click event triggers cell position change event - javascript

I need to define mouse click event for my each cell. I used cell:pointerup event; but this event is triggered when I change positions of cells too. How can I differentiate these 2 events?
Thanks in advance.

What you can do is to create a custom element view and distinct click from dragging by checking whether a pointermove event was triggered between pointerdown and pointerup events.
var ClickableView = joint.dia.ElementView.extend({
pointerdown: function () {
this._click = true;
joint.dia.ElementView.prototype.pointerdown.apply(this, arguments);
},
pointermove: function () {
this._click = false;
joint.dia.ElementView.prototype.pointermove.apply(this, arguments);
},
pointerup: function (evt, x, y) {
if (this._click) {
// triggers an event on the paper and the element itself
this.notify('cell:click', evt, x, y);
} else {
joint.dia.ElementView.prototype.pointerup.apply(this, arguments);
}
}
});
And then tell the joint.dia.Paper to use the view.
var paper = new joint.dia.Paper({
// el, width, height etc.
elementView: ClickableView
});
A fiddle can be found here.

Related

prevent all MouseClick event until page load

I have a situation in which i have to prevent all MouseClick events until the page loads.
i have 1 javascript function defined on page load like
onload="init();"
Now in function init(), we are showing tree and select a particular node of it.
function init() {
ExpandAncestors(node);
ExpandNode(node);
setTimeout("treeScrollToView()", 1000);
}
Now i want to prevent all the mouse click event on tree/page until whole tree is not fully shown.
I have searched through some of the posts related to my question but that uses event.preventDefault() but i dont have Event object here.
Any help is greatly appreciated.
You can use:
CSS
body {
pointer-events:none;
}
and then on page load reactivate them
$(document).ready(() => {
$('body').css('pointer-events', 'all') //activate all pointer-events on body
})
Explanation
pointer-events:none; blocks all mouse interaction with the elements it's applied to - Since the body is usually the parent of all the elements in your page, it would case them not to react to any mouse interaction at all.
Keep in mind that all mouse interaction would be blocked this way, not only mouse clicks but mouse hover, mouse up's etc etc..
I think the basic need is to prevent user from clicking the tree area. I would prefer to display an overlay div rather than playing with the tree mouse click events.
You can show a loading overlay on the tree part until it is loaded. once done, you can hide the loading and show your original tree.
Ref: How to completely DISABLE any MOUSE CLICK
JavaScript Only
You can have an event listener along with a boolean. onclick disables a click. oncontextmenu disables right clicks.
(function(){window.onload = function () {
var allowClicks = false;
document.onclick = function (e) { !allowClicks&&e.preventDefault(); }
document.oncontextmenu = function (e) { !allowClicks&&e.preventDefault(); }
document.getElementById('myElement').onload = function () { allowClicks = true; }
}());
myElement is your element which you can replace with whatever
Use this with one element
If you want to disable mouse clicks for just one element, do:
(function(){window.onload = function () {
var allowClicks = false,
elem = document.getElementById('myElement');
elem.onclick = function (e) { !allowClicks&&e.preventDefault(); }
elem.oncontextmenu = function (e) { !allowClicks&&e.preventDefault(); }
elem.onload = function () { allowClicks = true; }
}());
onload="init();" here you can have event object.
pass event as argument.
onload="init(event);"
now you can use that in init() function.
Try utilizing $.holdReady()
$.holdReady(true);
$(window).off("click");
$("*").each(function(i, el) {
this.onclick = function(e) {
e.preventDefault();
}
});
function init() {
$("div").on("click", function() {
alert($.now())
})
}
setTimeout(function() {
$.holdReady(false);
}, 7000)
$(function() {
init()
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<body>
<div>click</div>
click
</body>

Is there a way to trigger mouseup when leaving the document body?

I found some code and I made a jsfillde with it. I need to know how to trigger mouseup in the function below, when you leave document body (in the fiddle example it's like dragging the object into HTML section for instance and leave the mouse click there).
function handleMouseMove(e) {
if (canMove) {
var left = getMousePosX(e);
var top = getMousePosY(e);
var newLeft = ($(elemToMove).css('left').toDecNum() + (left - lastPosX));
var newTop = ($(elemToMove).css('top').toDecNum() + (top - lastPosY));
$(elemToMove).css('left', newLeft);
$(elemToMove).css('top', newTop);
lastPosX = left;
lastPosY = top;
}
return false;
}
Thanks for any suggestion.
You can use
document.onmouseout = handleMouseUp;
This says that when the mouse leaves the document object, the handleMouseUp handler should be called.
Updated fiddle:
http://jsfiddle.net/vp14utt1/1/
-
P.S. for event handlers that simply take the event as an argument, you can just use the function name without wrapping it.
document.onmousedown = function (e) { handleMouseDown(e); };
document.onmousedown = handleMouseDown;
$(elemToMove).trigger('mouseup');
Should do it.
Add this line (new Fiddle):
document.onmouseleave = function (e) { handleMouseUp(e); };
This fires your 'mouse up' logic when the mouse is dragged off the browser window.
To quote The difference between mouseout() and mouseleave():
The mouseout event triggers when the mouse pointer leaves any child elements as well the selected element.
The mouseleave event is only triggered when the mouse pointer leaves the selected element.
I think you want the later.

how to find out click event in canvas,kinetic js

I am trying to find click event on shape. when i click on shape like rectangle its become drag-gable but when i click outside of it,it should off its resizable feature.
i tried with blur function but doesn't work. i don't want it on mouse out.
problem is when i click on rectangle it gives me alert but when i click on canvas it gives me that alert twice because that shape is part of canvas.
so please suggest me how to distinguish between click on shape and out side of shape.
how to find out click event in canvas,kinetic js
you can try something like this
appendEvents: function(box, area){
_self = this;
// add cursor styling
box.on('mouseover', function() {
_self.draw = false;
document.body.style.cursor = 'pointer';
});
box.on('mouseout', function() {
document.body.style.cursor = 'default';
});
box.on('click', function() {
_self.draw = true;
_self.focusArea(area, box,box.attrs.x,box.attrs.y);
_self.openFocusArea(area,box,box.attrs.x,box.attrs.y);
});
box.on('dragend', function() {
_self.draw = false;
_self.dragArea(area, box);
});
},

Always suppress a click event after drag in d3

Decoupling of click and drag events is discussed in some previous questions here, e.g. this one
Typically, it is recommended to use if (d3.event.defaultPrevented === false) {...} in the click handler. However, this doesn't seem to work (at least in some browsers) if mouseup and mousedown are not in the same element. Consider this jsfiddle (code below). Here is the behavior I want: click anywhere in SVG triggers click event (rectangle flashes), drag anywhere in SVG drags the rectangle. Observed behavior (Chrome 33): if the mousedown of the click is inside the rectangle and mouseup is outside, both the drag and click events trigger. If both mousedown and mouseup are inside or both are outside, click event is not triggered.
Can someone explain why the click event is triggered if mouseup and mousedown are not in the same element, and how to reliably prevent this from happening?
var container, rect, dragBehavior;
svg = d3.select('svg').attr("width", 500).attr("height", 300);
container = svg.append('g');
rect = container.append('rect').attr('width', 100).attr('height', 100);
dragBehavior = d3.behavior.drag()
.on('dragend', onDragStart)
.on('drag', onDrag)
.on('dragend', onDragEnd);
svg.call(dragBehavior).on('click', onClick);
function flashRect() { rect.attr('fill', 'red').transition().attr('fill', 'black'); }
function onDragStart() { console.log('onDragStart'); }
function onDrag() {
console.log('onDrag');
var x = (d3.event.sourceEvent.pageX - 50);
container.attr('transform', 'translate(' + x + ')');
}
function onDragEnd() { console.log('onDragEnd'); }
function onClick(d) {
if (d3.event.defaultPrevented === false) {
console.log('onClick');
flashRect();
} else {
console.log("default prevented");
}
}
Add dragBehavior to the rectangle instead of the whole svg element.
Here is the fiddle link with the fix http://jsfiddle.net/Mn4Uk/27/
rect
.call(dragBehavior)
.on('click', onClick);

Differentiate between focus event triggered by keyboard/mouse

I'm using jquery ui autocomplete and want to decipher between focus events triggered by keyboard interaction and mouse interaction. How would I go about this?
$('input').autocomplete({
source: function(request, response) {
...
},
focus: function(event, ui) {
// If focus triggered by keyboard interaction
alert('do something');
// If focus event triggered by mouse interaction
alert('do something else');
}
});
Thanks
The only way I can think of doing this is to have a handler listen in on the keypress and click events, and toggle a boolean flag on/off. Then on the focus handler of your input, you can just check what the value of your flag is, and go from there.
Probably something like
var isClick;
$(document).bind('click', function() { isClick = true; })
.bind('keypress', function() { isClick = false; })
;
var focusHandler = function () {
if (isClick) {
// clicky!
} else {
// tabby!
}
}
$('input').focus(function() {
// we set a small timeout to let the click / keypress event to trigger
// and update our boolean
setTimeout(focusHandler,100);
});
Whipped up a small working prototype on jsFiddle (don't you just love this site?). Check it out if you want.
Of course, this is all running off a focus event on an <input>, but the focus handler on the autocomplete works in the same way.
The setTimeout will introduce a bit of lag, but at 100ms, it might be negligible, based on your needs.
You should actually be able to determine this from the event-Object that is passed into the focus-event. Depending on your code structure this might be different, but there is usually a property called originalEvent in there, which might be nested to some depth. Examine the event-object more closely to determine the correct syntax. Then test on mousenter or keydown via regular expression. Something like this:
focus: function(event, ui){
if(/^key/.test(event.originalEvent.originalEvent.type)){
//code for keydown
}else{
//code for mouseenter and any other event
}
}
The easiest and most elegant way I've found of achieving this is to use the "What Input?" library. It's tiny (~2K minified), and gives you access to the event type both in scripts:
if (whatInput.ask() === 'mouse') {
// do something
}
...and also (via a single data attribute that it adds to the document body) styles:
[data-whatinput="mouse"] :focus,
[data-whatinput="touch"] :focus {
// focus styles for mouse and touch only
}
I particularly like the fact that where you just want a different visual behaviour for mouse / keyboard it makes it possible to do that in the stylesheet (where it really belongs) rather than via some hacky bit of event-checking Javascript (though of course if you do need to do something that's not just purely visual, the former approach lets you handle it in Javascript instead).
The first thing that comes to mind is that you can find the position of the mouse and check to see if its within the position of the element
Use this to store the position of the element:
var input = $('#your_autocompleted_element_id'),
offset = input.offset(),
input_x = offset.top,
input_y = offset.left,
input_w = input.outerWidth(),
input_h = input.outerHeight();
Then use this to find absolute position of the mouse within the window:
var cur_mx, cur_my;
$(document).mousemove(function(e){
cur_mx = e.pageX;
cur_my = e.pageY;
});
Then in your autcomplete setup:
focus: function(event, ui) {
// mouse is doing the focus when...
// mouse x is greater than input x and less than input x + input width
// and y is greater than input y and less than input y + input height
if (cur_mx >= input_x && cur_mx <= input_x + input_w && cur_my >= input_y && cur_my <= input_y + input_h) {
// do your silly mouse focus witchcraft here
} else {
// keyboard time!
}
}
This can be handled using mousedown event, see my example below.
this.focusFrom = 'keyboard' =>
onFocus = () => {
if (this.focusFrom === 'keyboard') {
// do something when focus from keyboard
}
}
handleMouseDown = () => {
this.focusFrom = 'mouse';
}
handleOnClick = () => {
this.focusFrom = 'keyboard';
}

Categories

Resources