Skip to content

Instantly share code, notes, and snippets.

@davisford
Created February 2, 2012 19:59
Show Gist options
  • Save davisford/1725425 to your computer and use it in GitHub Desktop.
Save davisford/1725425 to your computer and use it in GitHub Desktop.
HTML/css/js editor using backbone.js, jquery-ui, and jsPlumb; jsPlumb endpoints are not behaving as expected here. They are transparent, and they do not drag along with their source or target.
body {
background-color:white; font-size:90%;
/*background-image:url(../images/dynamicAnchorBg.jpg); */
background-image:url(http://colourlovers.com.s3.amazonaws.com/images/patterns/222/222733.png?1221244242);
font-family:Helvetica;
height: 100%;
}
#editorCanvas {
position: absolute;
left:0;
right:0;
top:0;
bottom:0;
z-index: 0;
}
#toolbar a {
background-color:transparent;
}
#toolbar a:hover {
text-decoration:underline;
}
#toolbar {
cursor:drag;
background-color:white;
color:black;
border:0.25em solid #ddd;
position:absolute;
right:1em;
top:4em;
width:20em;
font-size:90%;
-moz-border-radius:1em;
border-radius:1em;
padding:1em;
z-index:1000;
opacity:0.9;
filter:alpha(opacity=90);
font-family:helvetica;
box-shadow: 2px 2px 19px #aaa;
-o-box-shadow: 2px 2px 19px #aaa;
-webkit-box-shadow: 2px 2px 19px #aaa;
-moz-box-shadow: 2px 2px 19px #aaa;
}
#toolbar ul {
list-style: none;
}
.item {
padding: 1em;
padding-left: 4em;
margin: 0.5em;
background: #666;
color: white;
cursor:pointer;
}
.item:hover {
font-weight: bold;
}
.dateitem {
background-image: url(../images/fc/32x32/calendar.png);
background-repeat: no-repeat;
background-position: 10px;
}
.ruleitem {
background-image: url(../images/fc/32x32/form.png);
background-repeat: no-repeat;
background-position: 10px;
}
.window {
cursor:move;
padding: 0.5em;
z-index: 1031;
}
.window fieldset {
border: none;
}
<!DOCTYPE html>
<html>
<head>
<title>DaisyWorks Demo Application</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="stylesheets/jquery-ui-1.8.17.custom/css/cupertino/jquery-ui-1.8.17.custom.css" type="text/css" media="all" />
<link rel="stylesheet" href="stylesheets/jquery.multiselect.css" type="text/css" media="all" />
<link rel="stylesheet" type="text/css" href="stylesheets/editor.css">
<!-- jQuery / UI -->
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.17/jquery-ui.min.js"></script>
<!-- jQuery multiselect plugin -->
<script type="text/javascript" src="javascripts/vendor/jquery.multiselect.min.js"></script>
<!-- jsPlumb -->
<script type="text/javascript" src="javascripts/vendor/jquery.jsPlumb-1.3.5-all-min.js "></script>
<!-- underscore / backbone -->
<script src="http://documentcloud.github.com/underscore/underscore-min.js"></script>
<script src="http://documentcloud.github.com/backbone/backbone-min.js"></script>
<script type="text/javascript" src="javascripts/editor.js"></script>
<script>
$(function(){
$(".item").draggable({
appendTo: "#editorCanvas",
helper: "clone"
});
$("#editorCanvas").droppable({
drop: function(event, ui) {
if(ui.draggable[0].innerHTML === "Date") {
var model = new ED.Models.Date;
new ED.Views.Date({model:model}).render();
} else if(ui.draggable[0].innerHTML === "Rule") {
new ED.Views.Rule({model: new ED.Models.Rule}).render();
}
}
});
}); // end on ready
</script>
</head>
<body onunload="jsPlumb.unload();" data-library="jquery">
<div id="editorCanvas">
<div id="toolbar" >
<h3>Widget Toolbar</h3>
<p>Drag the widgets on to the canvas to visually develop a rule for one or more Daisies.</p>
<ul>
<li class="item dateitem">Date</li>
<li class="item ruleitem">Rule</li>
<li class="item fakeitem">Fake</li>
</ul>
</div>
</div> <!-- end editor canvas -->
</body>
</html>
var ED = {
Models: {},
Collections: {},
Views: {},
Templates: {}
};
var PLUMBING = {
options: {
tolerance:'touch',
hoverClass:'dropHover',
activeClass:'dragActive'
},
stroke: "#00f",
endpoint : {
endpoint:"Rectangle",
paintStyle:{ width:25, height:21, fillStyle:this.stroke },
isSource:true,
isTarget:true,
scope:"blue rectangle",
connectorStyle : {
gradient:{stops:[[0, this.stroke], [0.5, "#09098e"], [1, this.stroke]]},
lineWidth:5,
strokeStyle:this.stroke,
dashstyle:"2 2"
},
dropOptions : this.options
}
};
(function($) {
// use mustache {{ template style }}
_.templateSettings = {
interpolate: /\{\{(.+?)\}\}/g
};
/* ##########################################
* MODELS
* ##########################################*/
ED.Models.Date = Backbone.Model.extend({
});
ED.Models.Rule = Backbone.Model.extend({
})
/* ##########################################
* TEMPLATES
* ##########################################*/
ED.Templates.Date = _.template(
"<div class='ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix'>"+
"<span class='ui-dialog-title'>Date</span>"+
"<a href='#' class='ui-dialog-titlebar-close ui-corner-all' role='button'>"+
"<span class='ui-icon ui-icon-closethick'>close</span>"+
"</a></div><div class='ui-widget-content dateWidget ui-dialog-content'>" +
"<form><fieldset><input type='text' class='datePicker'></fieldset></form></div>"
);
ED.Templates.Rule = _.template(
"<div class='ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix'>"+
"<span class='ui-dialog-title'>Rule</span>"+
"<a href='#' class='ui-dialog-titlebar-close ui-corner-all' role='button'>"+
"<span class='ui-icon ui-icon-closethick'>close</span>"+
"</a></div>"+
"<div class='ui-widget-content ui-dialog-content'>"+
"<form><fieldset><select class='daisy' multiple='multiple'>"+
"<option value='1'>Living Room</option>"+
"<option value='2'>Basement</option>"+
"<option value='3'>Kitchen</option>"+
"<option value='4'>A really, really, super long name</option></select>"+
"<select class='sensor' multiple='multiple'>"+
"<option value='1'>Power</option>"+
"<option value='2'>Leak Detection</option>"+
"<option value='3'>Magnetic Switch</option>"+
"<option value='4'>Humidity</option>"+
"<option value='5'>Temperature</option>"+
"<option value='6'>Moisture</option>"+
"<option value='7'>Battery</option></select>"+
"<select class='operator' multiple='multiple'>"+
"<option value='1'>Is Less Than</option>"+
"<option value='2'>Is Less Than Or Equal To</option>"+
"<option value='3'>Is Greater Than</option>"+
"</select>"+
"<input type='text' id='amount'/>"+
"<div class='slider'></div>"
);
/* #########################################
* VIEWS
* #########################################*/
ED.Views.Date = Backbone.View.extend({
template: ED.Templates.Date,
events: {
"click .ui-dialog-titlebar-close": "delete"
},
tagName: "div",
className: "window",
initialize: function() {
_.bindAll(this, 'render', 'remove', 'delete');
this.model.bind('destroy', this.remove);
},
render: function() {
$(this.el).attr('id', 'window_'+this.model.cid)
.addClass('ui-dialog')
.addClass('ui-widget-content')
.addClass('ui-corner-all')
.attr('tabIndex', '-1')
.html(this.template(this.model.toJSON));
$("#editorCanvas").append(this.el);
jsPlumb.draggable(this.el);
this.$(".datePicker").datepicker();
jsPlumb.addEndpoint(this.el, PLUMBING.endpoint);
},
remove: function() {
var me = $(this.el);
me.hide("explode", 1000, function(){
me.remove();
});
},
delete: function() {
this.model.destroy();
}
});
ED.Views.Rule = Backbone.View.extend({
template: ED.Templates.Rule,
events: {
"click .ui-dialog-titlebar-close": "delete"
},
tagName: "div",
className: "window",
initialize: function() {
_.bindAll(this, 'render', 'remove', 'delete');
this.model.bind('destroy', this.remove);
},
render: function() {
$(this.el).attr('id', 'window_'+this.model.cid)
.addClass('ui-dialog')
.addClass('ui-widget-content')
.addClass('ui-corner-all')
.attr('tabIndex', '-1')
.html(this.template(this.model.toJSON));
$("#editorCanvas").append(this.el);
jsPlumb.draggable(this.el);
this.$(".daisy").multiselect({
multiple: false,
header: "Choose a Daisy",
noneSelectedText: "No Daisy Selected",
selectedList: 1
});
this.$(".sensor").multiselect({
multiple: false,
header: "Choose a Sensor",
noneSelectedText: "No Sensor Selected",
selectedList: 1
});
this.$(".operator").multiselect({
multiple: false,
header: "Choose an Operator",
noneSelectedText: "No Operator Selected",
selectedList: 1
});
this.$(".slider").slider({
range: false,
min: 0,
max: 65534
});
jsPlumb.addEndpoint(this.el, PLUMBING.endpoint);
},
remove: function() {
var me = $(this.el);
me.hide("explode", 1000, function(){
me.remove();
});
},
delete: function() {
this.model.destroy();
}
});
/* #########################################
* PLUMBING
* #########################################*/
jsPlumb.Defaults.PaintStyle = { strokeStyle:'#666' };
jsPlumb.Defaults.EndpointStyle = { width:20, height:16, strokeStyle:'#666'};
jsPlumb.Defaults.Endpoint = "Circle";
jsPlumb.Defaults.Anchors = ["TopCenter", "BottomCenter"];
})(jQuery);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment