Nossidge
Nossidge

Reputation: 961

Find selected nodes/edges in cytoscape.js "on('unselect')" event

Background

When I tap a node, one event fires; the 'tap' event. When I then tap a different node, two events fire; the 'tap' event, then the 'unselect' event.

At first I thought it was a problem with on('tap') and on('unselect') event order, just because a human might think, "first I'm clearing my selection, and then I'm selecting a new node", but I can see why this is functioning as it should. A different node is tapped, so the 'tap' event fires; and then because the previous node is no longer selected, the 'unselect' event fires.

So, I think that it is working as it should, but its does mean that I need to code around this behaviour.

Details

What I want to do is to call some code in on('unselect') that will only run when no node/edge is selected. That would usually be when I click the background of the graph.

The problem is that cy.$('node:selected').length is always returning 0. And the same for edge:selected. See the below code.

So I'd just like to know if there are any workarounds for this? How can I query a graph's selected items in on('unselect')?

Context

I'm using the graph selection to filter the rows of a table, but when no node/edge is selected, I want the table to show all the data. Currently, each node/edge must be clicked twice for the on('tap') to not be overwritten by the on('unselect') unfilter code.

Steps to reproduce

var cy = cytoscape({
  container: document.getElementById('cy'),
  elements: [
    { data: { id: 'a' } },
    { data: { id: 'b' } },
    { data: { id: 'ab', source: 'a', target: 'b' } }
  ]
});
cy.on('tap', 'node', function(evt){
  console.log('event: tap node');
});
cy.on('tap', 'edge', function(evt){
  console.log('event: tap edge');
});
cy.on('unselect', function(evt){
  console.log('event: unselect');
  console.log('node:  ' + cy.$('node:selected').length);
  console.log('edge:  ' + cy.$('edge:selected').length);
});

When I tap a node, console logs the tap. When I tap a different node, console logs the tap, then logs the unselect.

So when I click a node, then an edge, then a node, then the background, the console log is:

event: tap node
event: tap edge
event: unselect
node:  0
edge:  0
event: tap node
event: unselect
node:  0
edge:  0
event: unselect
node:  0
edge:  0

As you can see, cy.$('node:selected').length is always 0.

Environment info

Cytoscape.js version: 3.15.0

Upvotes: 2

Views: 1946

Answers (1)

Ravenous
Ravenous

Reputation: 1160

Same principle as How to listen to drag event of CytoscapeJS node (including only the one directly under the cursor/finger)

Add a class of your choice, like .selected to the target(s) on tap and use that class when listening for unselect events or when querying for selected targets. Remove the class within your unselect handler logic, so no .selected targets stick around.

Upvotes: 1

Related Questions