I have a Protovis graph that responds to pan/zoom events like the sample on the website, which covers the Panel that holds the graph with an empty one. Unfortunately it captures all Events like mouseover and mouseout which my underlying graph usually responds to.
This is because you have to set the Panel to accept all events. According to the docs the only valid params for this are 'all', 'painted' and 'none'
vis.add(pv.Panel)
.events("all")
How can I prevent the zoom Panel from capturing these events? Or how can I pass them through to the Panel below it?
I don't think this is necessarily the answer you want, but as far as I can tell there's no easy way to pass events through to lower elements. However, if your graph is similar to the example, you can simply change the order of the invisible Panel and the marks that should receive events, from:
vis.add(pv.Dot)
.event('click', function() { alert("clicked") })
// ... etc
vis.add(pv.Panel)
.events("all")
// ... etc
to:
vis.add(pv.Panel)
.events("all")
// ... etc
vis.add(pv.Dot)
.event('click', function() { alert("clicked") })
// ... etc
This will change the z-order of the marks, so that the dots receive click events before the panel. It's a little less plug-and-play, as you have to insert the panel at the correct point in your existing graph, but it should work.
You can see a jsFiddle based on the example here: http://jsfiddle.net/nrabinowitz/Ctxrr/
EDIT: Per the comment below, this approach can be a problem for zoom events. The better approach, shown in this updated fiddle, is to make the invisible Panel the parent of the marks in question - events will automatically bubble up from child to parent, and if the child doesn't set a listener for an event, it won't interfere with the parent. So as long as all foreground marks that need to receive events are children of the pan/zoom Panel, this should work.
Related
I'm using the compound model and the cytoscape-compound-drag-and-drop extension to let the user manually reorganize the layout by grouping some nodes together and moving whole groups easily.
Now I want a button to toggle the display of these groups "boxes", but keep displaying all non-parent nodes.
I first tried hide() on parent nodes, but it also hides the children, so I switched to dynamically applying a class which specifies display:hidden.
It seemed to do the trick, but still the hidden box can be clicked and cytoscape default "visual feedback" for click applies, showing off the area where the hidden box still lies.
I tried plenty of things that didn't work:
- disable events from my hidden style class: tried events:no. Should I report this as a bug ?
- .ungrabify().unselectify().panify().lock()
- on click: destroy the event object
- set e.target._private.active = false
I tried a nasty hack: setting e.target._private.position = {}
The event is still fired, but destroying the position sucessfully prevents the "visual feedback" from happenning, my box effectively stays "hidden".
But still the event occurs on the wrong target: the box, not on the empty space of the cytoscape container. I can keep hacking and leave with it, but isn't there a simpler solution to ?
Is it possible to simply and truly pass through hidden parent nodes events ?
You haven't used events properly.
cy.$('node').forEach(node => {
node.events = 'no'; // will not work
});
The following does work, and you can also restore events whenever you want.
cy.$('node').forEach(node => {
node.style('events', 'no');
});
I am able to select object programatically using fabricjs. However, it does not behave like when one selects an object using mouse click. On a mouse click, the object comes under focus, and one can, for example, drag it. However, on programatic selection, I cannot immediately move an object. An example jsfiddle:
http://jsfiddle.net/ThzXM/1/
Programmatic selection:
canvas.setActiveObject(canvas.item(0));
What I would like to ultimately achieve is this: on clicking a button, a new rectangle is added to canvas, which the user can move around before placing it on canvas - without requiring extra clicks. Is it possible to do this in a cross-browser compatible way? (I know in some browsers I can fire a mouseclick event but most disallow it.)
You have to do this. Don´t forget to call setCoords() to update the bounding box of your object.
// Set the active element
canvas.setActiveObject(canvas.item(0));
// Set left, o right,or angle... check documentation.
//Don´t forget to call setCoords() after changes.
canvas.item(0).setLeft(80).setCoords();
//Then render the canvas
canvas.renderAll()
I've been searching around for this and can't seem to find anything.
Basically I've binded a "touchmove" event (via jQuery) to a set of divs.. what I was hoping would happen is, as you drag across each div (with out touchend) the div's attr "xyz" toggles from 0 to 1 aka meaning it's been touched.
$("#itBoardFront div").on('touchmove',function(e){
$(this).attr('data-hit',1);
})
As you can assume, this is not working. Only the element that's actually being hit on and moved on is getting the data-hit =1.
I was able to solve this by catching the coordinates of the touch end positions then comparing it with each potential div's x,y,w,h.
You will need to 'touch and then move' per div. This is due to the way the events are fire on your elements. You can see this example: http://jsfiddle.net/MpJUR/6/
In each div (except the first one that took it by default) you need to click/touch first and then move in order to get the event trigger.
BTW, the event will be trigger on each 'move' to it's not efficient. You might want to catch 'touchstart' per div and/or just work with 'touchmove' on a parent elem that contain all the divs.
I'm using qTip2 here, and need the ability to refresh the content of the tooltip while it is still active. The elements with the tooltip have a click event that does some calculations that can change what I want to be displayed in the tooltip.
I have tried calling the 'destroy' method and rebinding the qtip2 after each recalculation, and it works but only after moving the mouse away and bringing it back.
What I want to achieve is to force the currently active tooltip to redraw itself.
If you look in the documentation, there is a "set" method to change the content:
$('.selector').qtip('option', 'content.text', 'new content'); // Preferred
Is that what you're looking for?
Update: After testing out the api options, they seem to not be working properly, but I've found another method - here is a demo - hover over the tip for 1 sec to see it change.
// make sure you target a specific tip
var qapi = $('#tip1').data('qtip'),
newtip = 'new tooltip content'
qapi.options.content.text = newtip; // update content stored in options
qapi.elements.content.text(newtip); // update visible tooltip content
qapi.redraw(); // redraw to adjust tooltip borders
I am trying to combine JQuery UI sortable with droppable to create multiple pages for dropping and sorting things. I have setup a blog entry with a stand-along demo here:
http://whit.info/blog/2009/06/06/jquery-ui-combining-sortable-with-droppable/
and here is a jsFiddle:
http://jsfiddle.net/VUuyx/
Note that you can drag to sort the boxes, even into other columns. You can also click the page buttons to switch pages. My problem lies in combining these two features:
By using droppable, I've allowed the user to drag a box to a page button, the page will then switch, and the user can finish dragging it onto the newly revealed page. The problem is that when the page switches, the first column which appears under the dragged box doesn't have it's over event fire. You have to drag to another column, and then back to the first column to get the placeholder to appear.
I'm not sure, but I think I need to somehow clear the events, or fire them manually. The problem seems to stem from the fact that the dragged box is over the column when it is made visible.
Can you assist with this esoteric dilemma?
Thanks!
Update:
So I have been considering possible work arounds for this. Michal suggested firing the refresh method, which indeed doesn't solve the problem, but made me think about event issues.
It seems that when you mouse away and then back again, the proper events fire. Perhaps if I can manually fire the mouseout event for the first column, the reset will allow the mouseover event to fire properly.
I tried this:
$(".column:first").trigger('mouseout');
But I don't think that is the same as sortable's out event. Perhaps I should fire that event?
Maybe I'm misunderstanding the problem, but I don't think it has anything to do with the "page switching". If you turn on both pages at the same time and try to drag "Box 1" to a position above "Box 4", you'll see that it doesn't trigger that "Box 4"'s Sortable has received the Draggable until you go below "Box 4". This doesn't solve your problem, but perhaps will help you look in a better area for the solution.
See http://jsfiddle.net/nkBNP/7/ for a JSFiddle that demonstrates what I mean.
At least for the top down drop in I think the solution is somewhere in setting the box class to draggable and link it to the sortable object.
$(".box").draggable({
tolerance: 'point',
connectToSortable: '.column',
snap:false,
helper : 'clone',
});
This example creates a duplicate of the box but it does allow me to drag box 1 up to page 2 and slowly drag it down above box 5 and get placed into the top spot. It is very sensitive though. You may need to adjust the grids and snap to get it to work consistently for the casual user.
I can certainly imagine that a sortable object wouldn't expect something to come down from the top, because it expects things to be sorted from within the container. Droppable on the other hand expects things to enter from any direction.
Yeah adding $('.column').sortable("refresh");
to end of the show_page(id) function worked for me (only tested in firefox minefield):
function show_page(id) {
$('.page').removeClass('page_active');
$('#page_'+id).addClass('page_active');
$('.column').sortable("refresh");
}
Adding #edtechdev's answer to tolerance: 'intersect produced something I thought might satisfy you, Whit:
$(".column").sortable({
connectWith: '.column',
opacity: 0.4,
tolerance: 'intersect', //<--changed
placeholder: 'place_holder',
helper: function(event, el) {
var myclone = el.clone();
$('body').append(myclone);
return myclone;
},
}).disableSelection();
// ...
function show_page(id) {
$('.page').removeClass('page_active');
$('#page_'+id).addClass('page_active');
$('#page_'+id).find('.column:first').sortable('refresh'); //<- added
}
Check out drag and drop portal built using jQuery and Asp.Net MVC, it has all implementation in blog posts: http://lakkakula.wordpress.com/2009/06/15/web-2-0-portal-using-asp-net-mvc-microsoft-ajax-client-templates-and-jquery-with-drag-and-drop-widget-personalization/
Sortable has an undocumented option refreshPositions which automatically updates the position of your droppables when they are sortable as well. This prevents the placeholder from being droppable instead of the actual droppable.