JSFiddle - React, Tailwind, and code Playground
HTML
<script src="//cdnjs.cloudflare.com/ajax/libs/jsPlumb/1.4.1/jquery.jsPlumb-1.4.1-all-min.js"></script>
<div id="drawingArea" style="width:100%;min-height:500px;">
<div class="startpoint point window node" style="left: 150px; top:20px" data-nodetype="startpoint" id="startpoint">Start</div>
<div class="window menu" style="left: 600px" id="menuContainer">
<p style="text-align: center">Menu</p>
<div class="menu_button_container">
<div class="button_add_task button menu_button">Add Task</div>
<div class="button_add_decision button menu_button">Add Decision</div>
<button id="saveButton" class="button menu_button">Save</button>
<button id="loadButton" class="button menu_button">Load</button>
</div>
</div>
<div class="window task" style="left: 120px; top:200px; display:none;" data-nodetype="task" id="taskcontainer0">
<div class="ctrl_container">
<div class="button_remove">x</div>
</div>
<div class="details_container">
<label class="detail_label">Name</label>
<input value="" class="detail_text"/>
</div>
</div>
<div class="window decision" style="left: 250px; top:300px; display:none;" data-nodetype="decision" id="decisioncontainer0">
<div class="ctrl_container">
<div class="button_remove">x</div>
</div>
</div>
<div class="endpoint point window node" style="left: 150px; top:400px" data-nodetype="endpoint" id="endpoint">End</div>
</div>
<textarea id="jsonOutput" style="width:100%;height:100px;"></textarea>
CSS
.window {
}
.window:hover{
cursor: pointer;
}
.menu {
background-color: #EFEFEF;
border: 1px solid #346789;
box-shadow: 2px 2px 5px #AAAAAA;
color: black;
min-height: 3em;
position: absolute;
min-width: 5em;
}
.task {
background-color: #EEEEEF;
border: 1px solid #346789;
border-radius: 0.5em;
box-shadow: 2px 2px 5px #AAAAAA;
color: black;
min-height: 3em;
position: absolute;
min-width: 5em;
}
.point{
background-color: #333333;
border: 1px solid #AAAAAA;
border-radius: 50%;
box-shadow: 2px 2px 5px #AAAAAA;
color: white;
min-width: 50px;
min-height: 30px;
font-size:11pt;
padding:10px;
position: absolute;
text-align: center;
}
.point:hover {
box-shadow: 2px 2px 19px #AAAAAA;
}
.decision{
transform:rotate(-45deg);
overflow:hidden;
border: 1px solid #346789;
border-radius: 0.3em;
color: black;
backface-visibility: hidden;
background: none repeat scroll 0 0 #F4F4F4;
box-shadow: 0 0 0 1px #CCCCCC;
color: #000000;
display: block;
height: 80px;
overflow: hidden;
position: relative;
text-decoration: none;
width: 80px;
}
.decision .ctrl_container{
display: table-cell;
height: 80px;
padding: 0 10px;
text-align: center;
transform: rotate(45deg);
vertical-align: middle;
width: 80px;
}
.button {
text-align: center;
border: 1px solid;
margin: 5px;
}
.button:hover {
cursor: pointer;
}
.menu_button{
padding:5px;
}
.menu_button:hover{
background-color:#AAAAAA;
color:black;
}
.button_add{
background-color: #00CC00;
float:left;
border-radius: 50%;
box-shadow: 0px 3px 8px #aaa, inset 0px 2px 3px #fff;
padding:2px;
height:25px;
width:25px;
color:grey;
}
.button_add:hover{
background-color: #00AA00;
color:black;
}
.button_remove{
font-size:9pt;
color:darkgrey;
border-radius: 30%;
...
JavaScript
var numberOfElements = 0;
var htmlBase = 'drawingArea';
jsPlumb.ready(function () {
//FIX DOM:
$(("#taskcontainer0"))[0].innerHTML = $(("#taskcontainer0"))[0].innerHTML;
$(("#decisioncontainer0"))[0].innerHTML = $(("#decisioncontainer0"))[0].innerHTML;
jsPlumb.draggable($(".window"));
jsPlumb.importDefaults({
Endpoint : ["Dot", {radius:8}],
EndpointStyle : { fillStyle : "#4A6" },
HoverPaintStyle : {strokeStyle:"#42a62c", lineWidth:8 },
Connector:[ "Flowchart" ],
ConnectionOverlays : [
[ "Arrow", {
location:1,
id:"arrow",
length:20,
foldback:0.4
} ]
]
});
var workflowConnectorStartpoint = {
isSource: true,
isTarget: false,
maxConnections: 1,
anchor:"BottomCenter"
};
var workflowConnectorEndpoint = {
isSource: false,
isTarget: true,
maxConnections: -1,
anchor:"TopCenter",
paintStyle: { fillStyle: 'red' },
endpoint: ["Rectangle", {width:12, height:12}]
};
jsPlumb.addEndpoint(
$('.startpoint'),
workflowConnectorStartpoint
);
jsPlumb.addEndpoint(
$('.endpoint'),
workflowConnectorEndpoint
);
$('#'+htmlBase).on("click", ".button_remove", function () {
var parentnode = $(this)[0].parentNode.parentNode;
jsPlumb.detachAllConnections(parentnode);
jsPlumb.removeAllEndpoints(parentnode);
$(parentnode).remove();
});
$(".button_add_task").click(function () {
addTask();
});
$(".button_add_decision").click(function () {
addDecision();
});
$('#saveButton').click(function(){
saveFlowchart();
});
$('#loadButton').click(function(){
loadFlowchart();
});
});
function addTask(id){
if(typeof id === "undefined"){
numberOfElements++;
id = "taskcontainer" + numberOfElements;
}
$('<div class="window task node" id="' + id + '" data-nodetype="task" style="left:30px; top:30px;">').appendTo('#'+htmlBase).html($(("#taskcontainer0"))[0].innerHTML);
var taskSourceConnectorEndpoint = {
isSource: true,
isTarget: false,
maxConnections:...