I am using jsplumb to draw dynamic state machine diagram. On click of a button I need to add new box in a drawing area and allow user to position it as per their need.
I am not getting any proper easy to understand documentation for this. I tried few things:
var i=8;
function AddDiv() {
var obj = new Date();
var Div = $('<div/>', {
'class':'box ui-draggable ui-draggable-handle ui-droppable',
'id':'box_'+i,
'html':'BOXESNEW'
}).appendTo('.statemachine_cont');
jsPlumb.addEndpoint($(Div), targetEndpoint);
$(Div).draggable(
{
drag: function(){
jsPlumb.repaint($(this)); // (or) jsPlumb.repaintEverything(); to repaint the connections and endpoints
// jsPlumb.addEndpoint($(this));
}
});
$(Div).addClass('box ui-draggable ui-draggable-handle ui-droppable');
}
var a = $("#a");
//Setting up drop options
var targetDropOptions = {
activeClass: 'dragActive'
};
//Setting up a Target endPoint
var targetColor = "#BEBEBE";
var targetEndpoint = {
anchor: "BottomCenter", //Placement of Dot
endpoint: ["Dot", { radius: 8}], //Other types are rectangle, Image, Blank, Triangle
paintStyle: { fillStyle: targetColor }, //Line color
isSource: true, //Starting point of the connector
// scope: "green dot",
connectorStyle: { strokeStyle: "#5C96BC", lineWidth: 2 }, // Means Bridge width and bridge color
connector: ["Bezier"], //Other properties Bezier
maxConnections: -1, //No upper limit
isTarget: true, //Means same color is allowed to accept the connection
dropOptions: targetDropOptions //Means when the drag is started, other terminals will start to highlight
};
jsPlumb.bind("ready", function () {
//Set up endpoints on the divs
jsPlumb.addEndpoint($(".box ui-draggable ui-draggable-handle ui-droppable"), targetEndpoint);
jsPlumb.addEndpoint($(".box ui-draggable ui-draggable-handle ui-droppable"), sourceEndpoint);
jsPlumb.draggable($(".box ui-draggable ui-draggable-handle ui-droppable"));
jsPlumb.animate($("#a"), { "left": 50, "top": 100 }, { duration: "slow" });
});
Not sure what I have done is correct, I referred to some online code available and modified it.
My issue here is: Onclick of a button I am able to add a new box and also able to drag a connection from that box. But when I try to drag that box (i.e change its position), the connection does not move. Box is moved but I am unable to move the connection with the box.
When I try to move the newly added box or the box connected to new one, both the boxes can be moved but the connection remains static and doesn't move. where as if other boxes are moved it moves along with the connections. I have added a image of that for reference.
1st image shows how newly added box and new connection appears. 2nd image shows how moving of the box creates the issue.
Here is how I manged to get it working. I modified my entire code
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title> - jsFiddle demo</title>
<script type='text/javascript' src='js/jquery-1.10.1.js'></script>
<link rel="stylesheet" type="text/css" href="css/demo-all.css">
<link rel="stylesheet" type="text/css" href="css/demo.css">
<script type='text/javascript' src="js/jquery.ui.touch-punch-0.2.2.min.js"></script>
<script type='text/javascript' src="js/jquery-ui-1.9.2.min.js"></script>
<script type='text/javascript' src="js/jquery.jsPlumb-1.7.2-min.js"></script>
<style type='text/css'>
.hidden { display: none; }
</style>
<script type='text/javascript'>
$(window).load(function(){
function cloneWindow(instance) {
var $jspContainer = $("#statemachine-demo"),
divid = "fromTemplate_" + new Date().getTime().toString()
$cloneElement = $("<div class='w'>New Window <div class='ep'></div></div>").attr("id", divid);
$jspContainer.append($cloneElement);
instance.draggable(divid);
instance.makeSource($cloneElement, {
filter: ".ep", // only supported by jquery
anchor: "Continuous",
connector: ["StateMachine", {
curviness: 1
}],
connectorStyle: {
strokeStyle: "#5c96bc",
lineWidth: 2,
outlineColor: "transparent",
outlineWidth: 4
},
maxConnections: 10,
onMaxConnections: function (info, e) {
alert("Maximum connections (" + info.maxConnections + ") reached");
}
});
instance.bind("connection", function (info) {
info.connection.getOverlay("label").setLabel(info.connection.id);
});
instance.makeTarget($cloneElement, {
anchor:"Continuous",
dropOptions:{ hoverClass:"dragHover" }
});
}
jsPlumb.ready(function () {
$("#addwindow").click(function() {
cloneWindow(instance);
});
// setup some defaults for jsPlumb.
var instance = jsPlumb.getInstance({
Endpoint: ["Dot", {
radius: 2
}],
HoverPaintStyle: {
strokeStyle: "#1e8151",
lineWidth: 2
},
ConnectionOverlays: [
["Arrow", {
location: 1,
id: "arrow",
length: 14,
foldback: 0.8
}],
["Label", {
label: "Drag this and drop it on another element to make a connection.",
id: "label",
cssClass: "aLabel"
}]
],
Container: "statemachine-demo"
});
jsPlumb.importDefaults({
filter: ".ep",
anchor: "Continuous",
connector: ["StateMachine", {
curviness: 1
}],
connectorStyle: {
strokeStyle: "#5c96bc",
lineWidth: 2,
outlineColor: "transparent",
outlineWidth: 4
},
maxConnections: 10,
dropOptions: {
hoverClass: "dragHover"
}
});
var windows = jsPlumb.getSelector(".statemachine-demo .w");
// initialise draggable elements.
instance.draggable(windows);
// bind a click listener to each connection; the connection is deleted. you could of course
// just do this: jsPlumb.bind("click", jsPlumb.detach), but I wanted to make it clear what was
// happening.
instance.bind("click", function (c) {
instance.detach(c);
});
// bind a connection listener. note that the parameter passed to this function contains more than
// just the new connection - see the documentation for a full list of what is included in 'info'.
// this listener sets the connection's internal
// id as the label overlay's text.
instance.bind("connection", function (info) {
info.connection.getOverlay("label").setLabel(info.connection.id);
});
// suspend drawing and initialise.
instance.doWhileSuspended(function () {
// make each ".ep" div a source and give it some parameters to work with. here we tell it
// to use a Continuous anchor and the StateMachine connectors, and also we give it the
// connector's paint style. note that in this demo the strokeStyle is dynamically generated,
// which prevents us from just setting a jsPlumb.Defaults.PaintStyle. but that is what i
// would recommend you do. Note also here that we use the 'filter' option to tell jsPlumb
// which parts of the element should actually respond to a drag start.
instance.makeSource(windows, {
filter: ".ep", // only supported by jquery
anchor: "Continuous",
connector: ["StateMachine", {
curviness: 1
}],
connectorStyle: {
strokeStyle: "#5c96bc",
lineWidth: 2,
outlineColor: "transparent",
outlineWidth: 4
},
maxConnections: 10,
onMaxConnections: function (info, e) {
alert("Maximum connections (" + info.maxConnections + ") reached");
}
});
// initialise all '.w' elements as connection targets.
instance.makeTarget(windows, {
dropOptions: {
hoverClass: "dragHover"
},
anchor: "Continuous"
});
// and finally, make a couple of connections
instance.connect({
source: "opened",
target: "phone1"
});
instance.connect({
source: "phone1",
target: "inperson"
});
instance.connect({
source: "phone1",
target: "phone1"
});
});
});
});
</script>
</head>
<body>
<div class="demo statemachine-demo" id="statemachine-demo" style="border:2px solid;border-radius:25px;">
<button type="button" id="addwindow">Add Window</button>
<div class="w" id="opened">BEGIN
<div class="ep"></div>
</div>
<div class="w" id="phone1">PHONE INTERVIEW 1
<div class="ep"></div>
</div>
<div class="w" id="phone2">PHONE INTERVIEW 2
<div class="ep"></div>
</div>
<div class="w" id="inperson">IN PERSON
<div class="ep"></div>
</div>
<div class="w" id="rejected">REJECTED
<div class="ep"></div>
</div>
<div class="w hidden" id="template_newwindow">
<div class="ep"></div>
</div>
</div>
</body>
</html>