質問

Using jsPlumb, I managed to have the following setup:

  • There are multiple nodes acting like nodes in a special type of flowchart.
  • Each node has one single target where connections can be dropped onto.
  • Every node has zero, one or more exits. Each exit acts as jsPlumb source, and is allowed to have one connection at most.

Little example first: http://fiddle.darkspot.ch/ivr/flowchart/ivrplumb.html (after an hour of trying, I unfortunately didn't get it to run on jsFiddle - so I host it myself)

What I want to achieve is: If the user drags a new connection from an exit to another node, it should be established as intended. But all the other connections being on this exit should be removed.

I tried different approaches:

  • Having a click listener (links to jsPlumb documentation) on each exit bubble. Doesn't work -> the event never gets fired no matter what I tried.
  • Having an instance connection listener . I thought I could get the existing connections from the endpoint in the info object I'm receiving. Open the console while looking at the example, and you see it's always 1, no matter how many connections there are.
  • Limiting maxConnections for the makeSource(...) call to 1. This would actually work, but the user cannot drag another connection to replace the first.

Steps to reproduce:

  1. Move your mouse to one of the orange squares, click and drag a connection another node. (connection should establish)
  2. Open your browser's javascript console
  3. Move your mouse to the same square and click/drag another connection to the same or another target node. (second connection should establish. watch the console printing Number of connections:1. This should be 2 here)

What am I doing wrong?

役に立ちましたか?

解決

Before a new connection is established check whether the source already has outgoing connections, If so remove it. Assuming that exit elements have exit class:

jsPlumb.bind('beforeDrop', function(ci){ // Before new connection is created
    var src=ci.sourceId;
    var con=jsPlumb.getConnections({source:src}); // Get all source el. connection(s) except the new connection which is being established 
    if(con.length!=0 && $('#'+src).hasClass('exit')){
        for(var i=0;i<con.length;i++){
            jsPlumb.detach(con[i]);
        }
    }
    return true; // true for establishing new connection
});

他のヒント

Create a global array variable and push every new connections to the array

    var cons = [];
    instance.bind("connection", function (info) {
        var src = info.sourceId;
        var trgt = info.targetId;
        if (!cons.includes(src+trgt)) {//if not exists
           cons.push(src+trgt);
           cons.push(trgt+src);//(optional) use to prevent adding connection from target to source 
        }
    });

then in the beforeDrop check if the new connection that you are going to create already exists from the array.

    instance.bind('beforeDrop', function(info){
        var createCon = true;
        var src = info.sourceId;
        var trgt = info.targetId;
        var newCon = src + trgt;
        if(cons.includes(newCon)){//if new connection exists do not allow to create new connection
            createCon = false;
        }
        return createCon;
    });

And remove the element in the array when removing connections.

    instance.bind("click", function (info) {
        var el = cons.indexOf(info.sourceId + info.targetId);
        var el2 = cons.indexOf(info.targetId + info.sourceId);
        cons.splice(el, 1);
        cons.splice(el2, 1);
        instance.deleteConnection(info);
    });

I'm use JSPLUMB on angular project and i did this solution:

Delete the connection if exist, before drop a new connection:

    this.jsPlumbInstance.bind('beforeDrop', params => {
  // DELETA CONEXAO CASO JA EXISTE PARA CRIAR OUTRA
  // REMOVE CURRENT CONNECTION IF EXIST TO CREATE NEW
  this.jsPlumbInstance.getConnections().map(connection => {
    if (connection.targetId === params.targetId && connection.sourceId === params.sourceId) {
      this.jsPlumbInstance.deleteConnection(connection);
    }
  });
});

JSPLUMB haven't a 'afterDrop' bind, so keep this solution.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top