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');
});
Related
I have a div which I need to empty excluding a couple of divs inside it, the problem is, I have got it to work but the div's lose there jquery click functionality.
I have a stage which will have items dragged on them but I need to be able to empty these items but retain the click buttons which are also on the stage and stored in a div called keep.
I found this and it works but the things inside #keep still appear but they lose their jquery .click().
var $stage = $('#stage'), $noRemove = $stage.find('#keep');
$stage.html($noRemove);
This is because they are being removed and then re-added.
You either have to remove the children. OR Rebind the click method afterwards.
So for example:
$noRemove.click(function(...){});
See the Fiddle here : http://jsfiddle.net/r98dj/1/
Also, as a note. Make keep a class. Otherwise you'll end up with multiple divs with the same ID and this will cause you to fail W3C validation.
I have a css menu that also does child menus etc.. the problem is, I have to create eventHandlers for for tab/jaws users. It seems when I manipulate the menu(s) with show()/hide() it mucks up the inherent css selectors and their states, so if a user wanted to do both tab and mouse move - it won't work. They either have to use all mouse or tabbing etc..
I could create more js eventhandlers for mouseovers/outs etc..but curious if it would be feasible to clone the parent elements onload, and tie-into the tabbing that when they tabbed "off" the menu, I "revert" to this saved state so then the user can use the css method of mouseover/out etc..
Does this make sense? Or is this as much work/overhead as just creating more eventHandlers for the mouse events?
Here is an example of saving and restoring a menu just as you suggested.
http://jsfiddle.net/5pvGG/
var $saved = $('#cssmenu').clone();
$('#a').click( function() {
$('#cssmenu').remove();
});
$('#b').click( function() {
$('body').prepend($saved);
});
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 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.
Is it possible to use shift and mouse click to select multiple elements on a page using jquery?
I have several divs that i have given a tabindex to so that i can select them and can do things like delete them etc.
I want to be able to select more than 1 by holding down shift and using the mouse to click on each div and am struggling to do this.
Does anyone know how this can be done?
I did something like that some time ago, with jQuery:
$(id).click(function(event){ //Mouse Click+shift event
if(event.shiftKey){
//give some attribute that can indentify the elements of the selection
//example rel='multi-selection' or class='multi-selection'
}
});
Then you should do functions that select this elements and do whatever you need, I used this to drag multiple elements. Example if you want to delete this divs, you can for example:
function deleteMultiSelection(){
$('html').find('div[rel=multi-selection']).each(function(){
$(this).remove();
})
}
$("#button").click(function(){
deleteMultiSelection();
})
Be careful because I didn't test this code.
I have a jQuery plugin that does exactly what you want it is called finderSelect it enables Shift+Click, Ctrl+Click, Ctrl+Click+Drag and Standard Clicking on any element.
It sounds like jQuery UI Selectable is what you're after, you can try it out here.
To stay with OS conventions, they key it uses is Ctrl and not Shift, this isn't an option you can change without changing the jQuery UI code itself. It also has the feature of click and drag over elements to get a rectangular selection as well...if that's of any use.
Sure, if you are willing to do some work :)
Listen for the shift keydown, set a var that you can access from within your click handler functions, if the var is set then add that item, (or their tabindex for your current implementation) to your list of items to operate on when an 'action button' is pressed.
unset the var when you get the shift keyup event.
To be honest, the Ctrl + left click for selecting multiple items is pretty standard UI behaviour and built-in to the jQueryUI Selectable. Did you also know you can left click and drag a focus over multiple items to select them?
However, I can see an advantage in offering the behaviour in question, so how about using left click or drag to select and then left click and drag to also de-select?
It may not be the most efficient way of doing it, but after playing around with the in-built callbacks, I've come up with something that seems to work. Based on the code in your question I've hooked into the in-built callback functions to store what was selected and also handle the selection removal. JavaScript duplicated below but