利用jQuery-UI和jsPlumb实现拖拽连接模型

时间:2022-08-01 14:03:54

简介

之前公司需要做一个自定义数据搜索模型的功能,大体是这样的:左边显示的每一个模型对应于数据库中的一个表,把左边的模型拉入右边的容器内,会显示这个模型(也就是表)下的列信息,然后通过连线确定各独立的模型之间的关系(对应于数据库中的多表链接查询),然后保存数据到后台执行。由于保存模型就是对容器中的模型的一个解析,这里就不做展示了,这个demo主要处理模型的展示以及如何链接。 
话不多说,先上图: 
利用jQuery-UI和jsPlumb实现拖拽连接模型

需要用到的东西

这个功能主要用到的是jQuery UI的拖拽功能以及jsPlumb连线插件。 
jsPlumb插件是一个js插件,其主要功能是对网页上任意两个元素,都可以通过为他们添加endPoint节点来实现在这两个元素之间建立一个连接(就是画一条线)。这个插件有收费版、和社区版,收费版可能功能更强大,在这里用的是社区版,只要能处理我们的需求就可以了。用这个插件只需要jsPlumb-x.x.x.js即可,官网地址:https://jsplumbtoolkit.com/


下面介绍我的demo: 
完整demo下载地址:http://download.csdn.net/download/csdn_xuexiaoqiang/9784381 
在这个demo里,样式和HTML我写在了demo.html,js我写在了demo.js,用到的示例数据我写在了metadata.js,是一个数组。其他主要的东西还有:jquery-2.1.4.min.js、jquery-ui.min.js、jquery-ui.custom.min.css、jsPlumb-2.2.8.js剩下的bootstrap相关的都是为了页面美观我才加进去的,和核心功能无关。 
至于jsPlumb的用法,在demo.js中我都有标记。

数据处理的例子

这是我之前做的一个模块,里面有怎么保存模型数据的方法,仅供参考。 
jsp页面,页面本身没什么,而且是镶嵌在框架里面的,主要是页面下面的js,有主要的处理逻辑

 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path;
%>
<c:set var="ctx" value="<%=basePath%>"></c:set>
<html>
<head>
<title>模型定义</title>
<link rel="stylesheet" href="${ctx }/bootstrap/css/bootstrap.min.css" />
<link rel="stylesheet"
href="${ctx }/bootstrap/css/jquery-ui.custom.min.css" />
<link rel="stylesheet" href="${ctx }/zTree/css/zTreeStyle/zTreeStyle.css ">
<script type="text/javascript" src="${ctx }/js/jquery-2.1.4.min.js"></script>
<script type="text/javascript" src="${ctx }/js/jquery-ui.min.js"></script>
<script type="text/javascript" src="${ctx }/js/jsPlumb-2.2.8.js"></script>
<script src="${ctx }/bootstrap/js/bootstrap.min.js"></script>
<script src="${ctx }/bootstrap/js/bootbox.js"></script>
<script src="${ctx }/zTree/js/jquery.ztree.core.js"></script>
<script src="${ctx }/zTree/js/jquery.ztree.exedit.js"></script>
<style type="text/css">
.navRight li a {
font-size: 12px!important;
}
.footer {
height: auto;
margin-top: 10px;
text-align: center;
width: auto;
font: 12px/1.5 tahoma,arial,simsun,sans-serif;
padding-top: ;
}
.userHandle a,span {
box-sizing: content-box;
}
.userHandle {
box-sizing: content-box;
}
body {
background-color: #cbdde4;
}
/*ztree*/
.ztree li span.button.noline_open {
background: url(${ctx }/zTree/images/tree_close.png) no-repeat!important;
width: 10px!important;
height: 10px!important;
vertical-align: middle!important;
margin: 9px 9px 9px 0px!important;
}
.ztree li span.button.noline_close {
background: url(${ctx }/zTree/images/tree_open.png) no-repeat!important;
width: 10px!important;
height: 10px!important;
vertical-align: middle!important;
margin: 9px 9px 9px 0px!important;
}
.ztree li a span.button.ico_open {
background: url(${ctx }/zTree/images/tree_level2.png) no-repeat!important;
}
.ztree li a span.button.ico_close {
background: url(${ctx }/zTree/images/tree_level2.png) no-repeat!important;
}
.ztree>li>a>span.button.ico_open {
background: url(${ctx }/zTree/images/tree_level1.png) no-repeat!important;
}
.ztree>li>a>span.button.ico_close {
background: url(${ctx }/zTree/images/tree_level1.png) no-repeat!important;
}
.ztree li a span.button.ico_docu {
background: url(${ctx }/zTree/images/tree_level3.png) no-repeat!important;
}
.ztree *{
font-family: SimHei!important;
font-size: 18px!important;
color: #!important;
}
.ztree li a {
margin-bottom: 5px!important;
height: 28px!important;
line-height: 28px!important;
}
.ztree li a.curSelectedNode {
border: 1px solid #2983cf!important;
background: #d5ecf9!important;
}
.ztree li span.button {
height: 28px!important;
width: 20px!important;
line-height: 28px!important;
text-align: center;
vertical-align: middle!important;
}
.ztree>li{
margin-bottom: 4px!important;
}
.ztree ul {
padding-left: 28px!important;
}
.ztree li span.button.chk {
width: 13px!important;
height: 13px!important;
}
.ztree li span{
z-index: ;
}
/*ztree-end*/ #container {
min-height: 800px;
position: relative;
border: 1px solid #;
background-color: #ffffff;
border-radius: 5px;
z-index: ;
overflow: auto;
}
#container .model table {
border: 1px solid #ddd;
border-radius: 5px;
margin-bottom: ;
}
#container .model table thead th{
background-color: #3E7E9C;
text-align: center;
background-image: none;
}
#container .model table tbody{
background-color: #CBEAE1;
}
.jtk-endpoint, .endpointTargetLabel, .endpointSourceLabel {
cursor: pointer;
}
</style>
</head>
<body>
<div class="container-fluid">
<div class="row">
<div class="col-xs-2" style="min-height: 800px;background-color: #84ACB3;border-radius:5px;padding-top: 12px;">
<div class="content_wrap" style="width: 100%;">
<div class="zTreeDemoBackground left" style="width: 100%;">
<ul id="leftMenu" class="ztree" style="height: 800px;overflow: auto;width: 100%;"></ul>
</div>
</div>
</div>
<div class="col-xs-10">
<div id="container"></div>
</div>
</div>
</div>
<div style="padding-top: 10px;">
模型名称:<input type="text" value='' id="modelName" style="height: 32px;margin-right:5px;"/>
模型描述:<input type="text" value='' id="modelDesc" style="height: 32px;margin-right:5px;"/>
<button class="btn btn-white btn-info" type="button" onclick="save()" style="display: inline-block;">
<i class="ace-icon fa fa-check bigger-120 blue"></i> 保存</button>
</div>
<div id="myModal" class="modal fade" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title" id="myModalLabel">请选择模型联系条件</h4>
</div>
<div class="modal-body">
连线类型:<select id="twoWay">
<option value="false">单向</option>
<option value="true">双向</option>
</select>
条件:<select id="select_sourceList">
</select>
<select id="select_comparison" >
<option value="=" selected="selected">=</option>
</select>
<select id="select_targetList">
</select>
</div>
<div class="modal-footer">
<button id="submit_label" type="button" class="btn btn-primary" data-dismiss="modal">确定</button>
</div>
</div>
</div>
</div> <!-- javascript -->
<script type="text/javascript" src="${ctx }/js/model/addModel.js"></script> <script type="text/javascript">
$(document).ready(function(){ getDataSet("${ctx }/ajaxGetDataSet.do"); //监听新的连接
instance.bind("connection", function (connInfo, originalEvent) {
init(connInfo.connection);
});
// listen for clicks on connections, and offer to delete connections on click.
instance.bind("dblclick", function (conn, originalEvent) {
if (confirm("要删除从 " + conn.source.getElementsByTagName("th")[].innerHTML
+ " 到 " + conn.target.getElementsByTagName("th")[].innerHTML + " 的连接么?")){
instance.detach(conn);
}
});
});
function save(){
//下面两个只是到后台执行相关业务逻辑的链接,在后面的js中会用到,所以弄了一个变量,传到saveToDb方法中
var ajaxToVerifySql = "这里只是一个异步保存并执行所产生的SQL语句的链接";
var ajaxToSaveModel = "这个是保存模型相关数据的链接";
//保存到数据库
saveToDb(ajaxToVerifySql,ajaxToSaveModel);
}
</script>
</body>
</html>

下面就是页面引用的addModel.js,整个js都在这里:

 /**
* 添加自定义模型
*/
var model_counter=;
var dataSet;
var mData;
var treeObj; //初始化一个jsPlumb实例
var instance = jsPlumb.getInstance({
DragOptions: { cursor: "pointer", zIndex: },
ConnectionOverlays: [
[ "Arrow", {
location: ,
visible:true,
width:,
length:,
direction:,
id:"arrow_forwards"
} ],
[ "Arrow", {
location: ,
visible:true,
width:,
length:,
direction:-,
id:"arrow_backwards"
} ],
[ "Label", {
location: 0.5,
id: "label",
cssClass: "aLabel"
}]
],
Container: "container"
});
instance.importDefaults({
ConnectionsDetachable:true,
ReattachConnections:true
}); //创建模型
function CreateModel(ui, selector) {
//添加html模型
var modelid = $(ui.draggable).attr("id").split("_span")[];
model_counter++;
var id = modelid + "_model_" + model_counter;
var type = treeObj.getNodeByTId(modelid).id;
var add_html = getModelTable(ui, type);
$(selector).append('<div class="model" id="'
+ id +'" modelType="' + type
+ '" >'+add_html+'</div>');
var left = parseInt(ui.offset.left - $(selector).offset().left);
var top = parseInt(ui.offset.top - $(selector).offset().top);
$("#"+id).css("position", "absolute").css("left", left).css("top", top);
//添加连接点
instance.addEndpoint(id, { anchors: "RightMiddle" }, hollowCircle);
instance.addEndpoint(id, { anchors: "LeftMiddle" }, hollowCircle);
instance.addEndpoint(id, { anchors: "TopCenter" }, hollowCircle);
instance.addEndpoint(id, { anchors: "BottomCenter" }, hollowCircle);
//instance.draggable(id);
//注册实体可draggable
$("#" + id).draggable({
containment: "parent",
drag: function (event, ui) {
instance.repaintEverything();
},
stop: function () {
instance.repaintEverything();
}
});
return id;
}
//基本连接线样式
var connectorPaintStyle = {
stroke: "#84ACB3",
strokeWidth:
};
//鼠标悬浮在连接线上的样式
var connectorHoverStyle = {
strokeWidth: ,
stroke: "#84ACB3",
outlineWidth: ,
outlineStroke: "#84ACB3"
};
//端点样式设置
var hollowCircle = {
endpoint: ["Dot",{ cssClass: "endpointcssClass"}], //端点形状
connectorStyle: connectorPaintStyle,
// connectorHoverStyle: connectorHoverStyle,
paintStyle: {
fill: "#84ACB3",
radius:
}, //端点的颜色样式
isSource: true, //是否可拖动(作为连接线起点)
connector: ["Flowchart", {stub: , gap: , coenerRadius: , alwaysRespectStubs: true, midpoint: 0.5 }],
isTarget: true, //是否可以放置(连接终点)
maxConnections: -
};
//获得对应模型名称的模型
function getModelTable(ui, type)
{
var thead = $(ui.helper).html();
var list_tr = "";
for(var i = ; i < dataSet.length;i++){
var data = dataSet[i];
if(data.key == type){
for(var y = ;y < data.content.length;y++){
var col = data.content[y];
list_tr += '<tr><td>' + '<input type="checkbox" value="' + col.field + '">'
+ col.label
+ '</td><td></td></tr>';
}
}
}
var table = '<table class="table">'
+ '<thead><th>' +thead+ '</th><th><a href="javascript:void(0)" onclick="removeElement(this);" style="color:black;">X</a></th></thead>'
+ '<tbody>'
+ list_tr
+ '</tbody>'
+ '</table>';
return table;
}
//设置连接Label的label
function init(conn)
{
var label_text;
$("#select_sourceList").empty();
$("#select_targetList").empty();
var sourceName = $("#" + conn.sourceId).attr("modelType");
var targetName = $("#" + conn.targetId).attr("modelType");
for(var i = ; i < dataSet.length; i++){
if(dataSet[i].key == sourceName){
for(var y = ;y < dataSet[i].content.length; y++){
var text = '<option value="'+dataSet[i].value + '.' + dataSet[i].content[y].label +'">'+dataSet[i].value + '.' + dataSet[i].content[y].label + '</option>';
$("#select_sourceList").append(text);
}
}else if(dataSet[i].key == targetName){
for(var y = ;y < dataSet[i].content.length; y++){
var text = '<option value="'+dataSet[i].value + '.' + dataSet[i].content[y].label +'">' +dataSet[i].value + '.' + dataSet[i].content[y].label + '</option>';
$("#select_targetList").append(text);
}
}
}
$("#submit_label").unbind("click");
$("#submit_label").on("click",function(){
setlabel(conn);
});
$("#myModal").modal();
//connection.getOverlay("label").setLabel("点击此处添加模型关联条件");
}
//setlabel
function setlabel(conn)
{
conn.getOverlay("label").setLabel($("#select_sourceList").val()
+ ' '
+ $("#select_comparison").val()
+ ' '
+ $("#select_targetList").val());
if($("#twoWay").val()=="true"){
conn.setParameter("twoWay",true);
}else{
conn.setParameter("twoWay",false);
conn.hideOverlay("arrow_backwards");
}
}
//删除节点
function removeElement(obj)
{
var element = $(obj).parents(".model");
if(confirm("确定删除该模型?"))
instance.remove(element);
}
//获取原始数据
function getDataSet(uri)
{
$.ajax({
type: "post",
url: uri,
success: function(data){
dataSet = data.dSet;
mData = data.mData;
getLeftMenuList(dataSet);
},
error:function(data){
myalert("内部错误");
}
});
}
//设置左边模型列表
function getLeftMenuList(dataList)
{
var setting = {
data: {
simpleData: {
enable: true,
idKey: "id",
pIdKey: "pId",
rootPId: "root"
}
},
callback: {
onNodeCreated: zTreeOnNodeCreated
},
view : {
showLine: false
}
};
//初始化一级节点
var zNodes = [
{id:"dns",pId:"root",name:"DNS",isParent:true},
{id:"vpn",pId:"root",name:"VPN",isParent:true},
{id:"url",pId:"root",name:"URL",isParent:true},
{id:"terminal",pId:"root",name:"终端ID",isParent:true},
{id:"remoteControl",pId:"root",name:"远程控制",isParent:true},
{id:"netDisk",pId:"root",name:"网盘",isParent:true},
{id:"mail",pId:"root",name:"邮箱",isParent:true},
{id:"ip",pId:"root",name:"IP地址",isParent:true},
{id:"instantMessage",pId:"root",name:"即时通讯",isParent:true},
{id:"fiveTule",pId:"root",name:"五元组",isParent:true},
{id:"defence",pId:"root",name:"突防工具",isParent:true},
{id:"cookie",pId:"root",name:"COOKIE",isParent:true},
{id:"adsl",pId:"root",name:"Radius",isParent:true},
{id:"accountPassword",pId:"root",name:"账号口令",isParent:true},
{id:"newTable",pId:"root",name:"自定义",isParent:true}
]; for(var i=; i < dataList.length; i++){
var node = new Object();
if((dataList[i].oriName != "")&&(dataList[i].oriName != null)){
node.pId = dataList[i].oriName;
}else{
node.pId = "newTable";
}
node.id = dataList[i].key;
node.name = dataList[i].value;
zNodes.push(node);
}
//初始化
treeObj = $.fn.zTree.init($("#leftMenu"), setting, zNodes);
}
//拖拽设置
function zTreeOnNodeCreated()
{
//左边区域的draggable事件
$("#leftMenu .node_name").draggable({
helper: "clone",
scope: "plant"
});
//中间拖拽去的drop事件
$("#container").droppable({
scope: "plant",
drop: function (event, ui) {
//创建模型到拖拽区
CreateModel(ui, $(this));
}
});
}
//保存模型
function saveToDb(ajaxToVerifySql,ajaxToSaveModel)
{
var flag = true;
var ary = new Array();
$("input[type=checkbox]:checked").each(function(){
var val = this.value.toLocaleLowerCase();
ary.push(val);
});
flag = mm(ary);
if(!flag){
if(!checkOn()){
var modelName = $("#modelName").val();
var modelDesc = $("#modelDesc").val();
var result = exportData();
var result_sql = exportSQL(result); if(modelName.length == ){
myalert("请输入模型名称");
}else if(modelDesc.length == ){
myalert("请输入模型描述");
}else {
var items = new Array(); // 保存model涉及到的表名称
var jItems = new Array(); // 保存表以及对应的列名称
var kItems = new Array(); // 保存表以及对应的列名称 var nodes = result.nodes;
for(var property in nodes){
var dataSetJSON = nodes[property].data;
items.push(dataSetJSON.key+ "!" + nodes[property].name);
} uniqueArray(items);
for(var i=;i<items.length;i++){
var alias = items[i].split("!")[];
var tableName = items[i].split("!")[];
for(var j=;j<mData.length;j++){
if(tableName == mData[j]['tableName']){
mData[j]["alias"] = alias;
jItems.push(JSON.stringify(mData[j]));
break;
}
}
}
for(var i=;i<jItems.length;i++){
kItems.push(JSON.parse(jItems[i]));
} var submitData = {"modelName":modelName,"modelDesc":modelDesc,"modelJson":JSON.stringify(result),"modelSql":result_sql,"modelTable":JSON.stringify(kItems)};
var sqlData = {"modelSql":result_sql};
$.ajax({
type:"post",
url:ajaxToVerifySql,
data:sqlData,
success:function(data){
if(data == "success"){
$.ajax({
type:"post",
url:ajaxToSaveModel,
data:submitData,
success:function(data){
if(data.status == "success"){
myalert("保存成功");
}else{
myalert("保存失败");
}
},
error:function(data){
myalert("保存失败");
}
});
}else{
myalert("请检查模型连线是否正确以及是否有选择模型的列");
}
},
error:function(data){
myalert("保存失败");
}
});
}
}else{
myalert("请选择连接条件");
}
}else{
myalert("不能选择重复的列名称");
}
}
//把模型导出到一个变量中
function exportData()
{
var retStr = '{"nodes":{'; if($("#container").children().length > ){
$("#container .model").each(function(i){
var nodeStr = "";
nodeStr += '"' + $(this).attr("id") + '":{"name":"' + $(this).attr("id") + '"'
+ ',' + '"left":"' + $(this).css("left") + '"'
+ ',' + '"top":"' + $(this).css("top") + '"'
+ ',' + '"type":"' + $(this).attr("modelType") + '"'
+ ',';
var data = new Object();
var key = $(this).attr("modelType");
var value;
var content;
for(var y = ;y < dataSet.length; y++){
var ds = dataSet[y];
if(ds.key == key){
value = ds.value;
content = ds.content;
}
}
$(this).find("input:checked").each(function(n){
var field = $(this).val();
for(var y = ;y < content.length; y++){
var col = content[y];
if(col.field == field)
col.checked = true;
}
});
data.value = value;
data.key = key;
data.content = content;
nodeStr += "\"data\":" + JSON.stringify(data) + "}";
if((i+) < $("#container .model").length)
nodeStr += ','
retStr += nodeStr;
});
retStr += '},';
//连接
var connections = instance.getAllConnections();
if(connections.length > ){
var lineStr = '"lines":{';
for(var i = ; i < connections.length; i++){
var sourceId = connections[i].sourceId;
var targetId = connections[i].targetId;
var label = connections[i].getOverlay("label").label;
var twoWay = connections[i].getParameter("twoWay");
var str = '"demo_line_' + i + '":{'
+ '"from":"' + sourceId + '"'
+ ',' + '"to":"' + targetId + '"'
+ ',' + '"label":"' + label + '"'
+ ',' + '"twoWay":' + twoWay
+ '}';
if((i+) < connections.length)
str += ',';
lineStr += str;
}
lineStr += '}';
retStr += lineStr;
}else{
myalert("请检查模型连线是否正确");
return false;
}
}else{
myalert("请选择模型");
}
retStr += '}';
var retObj = JSON.parse(retStr);
return retObj;
}
//生成SQL
function exportSQL(retObj)
{
var fields = "";
var join = "";
var nodeData = retObj.nodes;
var lineData = retObj.lines;
var num = ;
for(var k in lineData){
var lf = lineData[k].from;
var lt = lineData[k].to;
var ll = lineData[k].label;
var twoWay = lineData[k].twoWay;
var f_node = nodeData[lf];
var t_node = nodeData[lt]; var f_d = f_node.data;
var f_node_name = f_node.name;
var t_d = t_node.data;
var t_node_name = t_node.name; var from_table_name = f_d.value;
var from_table = f_d.key;
var to_table_name = t_d.value;
var to_table = t_d.key; for(var i=; i<f_d.content.length; i++){
var f_field = f_d.content[i];
if(f_field.checked){
var fld = f_node_name+"."+f_field.field + " as " + "A" + num++ +"_" + f_field.field;
if(fields.indexOf(fld)<){
fields+=fld + ",";
}
}
} for(var i=; i<t_d.content.length; i++){
var t_field = t_d.content[i];
if(t_field.checked){
var fld = t_node_name+"."+t_field.field + " as " + "B" + num++ +"_" + t_field.field;
if(fields.indexOf(fld)<){
fields+=fld+",";
}
}
} var j_array = ll.split("=");
var j_from_table_name = $.trim(j_array[].split(".")[]);
var j_from_table_filed = $.trim(j_array[].split(".")[]);
var j_to_table_name = $.trim(j_array[].split(".")[]);
var j_to_table_filed = $.trim(j_array[].split(".")[]); j_from_table_name = j_from_table_name.replace(from_table_name,f_node_name);
j_from_table_filed = getFieldByLabel(f_d.content,j_from_table_filed);
j_to_table_name = j_to_table_name.replace(to_table_name,t_node_name);
j_to_table_filed = getFieldByLabel(t_d.content,j_to_table_filed);
var on = j_from_table_name + "." + j_from_table_filed + "=" + j_to_table_name + "." + j_to_table_filed;
if(twoWay){
if("" == join)
join += from_table + " " + f_node_name + " inner join " +to_table+ " " + t_node_name + " on "+on;
else
join += " inner join " + to_table + " " + t_node_name + " on " +on;
}else{
if("" == join)
join += from_table+" " + f_node_name + " left join "+to_table+ " " + t_node_name+" on "+on+" ";
else
join += " left join "+to_table+ " " + t_node_name+" on "+on+" ";
}
}
if(fields.length>)
fields = fields.substring(,fields.length-); return ("select " + fields + " from " +join);
}
//根据label获取field
function getFieldByLabel(obj,label)
{
var field;
for(var i=; i<obj.length; i++){
if(obj[i].label == label)
field = obj[i].field;
}
return field;
}
//去除重复数据
function uniqueArray(data)
{
data = data || [];
var a = {};
for (var i=; i<data.length; i++) {
var v = data[i];
if (typeof(a[v]) == 'undefined'){
a[v] = ;
}
};
data.length=;
for (var i in a){
data[data.length] = i;
}
return data;
}
//判断数组元素是否重复,重复返回ture
function mm(a)
{
return /(\x0f[^\x0f]+)\x0f[\s\S]*\/.test("\x0f"+a.join("\x0f\x0f") +"\x0f");
}
//检查连线是否有连接条件
function checkOn(){
var flag = false;
$(".aLabel").each(function(){
if("" == $(this).text()){
flag = true;
return false;
}
});
return flag;
}
//弹窗
function myalert(info) {
bootbox.dialog({
"message" : info,
"buttons" : {
"success" : {
"label" : "OK",
"className" : "btn-sm btn-primary"
}
}
});
}

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%><%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path;
%><c:set var="ctx" value="<%=basePath%>"></c:set><html><head><title>模型定义</title><link rel="stylesheet" href="${ctx }/bootstrap/css/bootstrap.min.css" /><link rel="stylesheet"
href="${ctx }/bootstrap/css/jquery-ui.custom.min.css" /><link rel="stylesheet" href="${ctx }/zTree/css/zTreeStyle/zTreeStyle.css "><script type="text/javascript" src="${ctx }/js/jquery-2.1.4.min.js"></script><script type="text/javascript" src="${ctx }/js/jquery-ui.min.js"></script><script type="text/javascript" src="${ctx }/js/jsPlumb-2.2.8.js"></script><script src="${ctx }/bootstrap/js/bootstrap.min.js"></script><script src="${ctx }/bootstrap/js/bootbox.js"></script><script src="${ctx }/zTree/js/jquery.ztree.core.js"></script><script src="${ctx }/zTree/js/jquery.ztree.exedit.js"></script><style type="text/css">
.navRight li a {
font-size: 12px!important;
}
.footer {
height: auto;
margin-top: 10px;
text-align: center;
width: auto;
font: 12px/1.5 tahoma,arial,simsun,sans-serif;
padding-top: 0;
}
.userHandle a,span {
box-sizing: content-box;
}
.userHandle {
box-sizing: content-box;
}
body {
background-color: #cbdde4;
}
/*ztree*/
.ztree li span.button.noline_open {
background: url(${ctx }/zTree/images/tree_close.png) no-repeat!important;
width: 10px!important;
height: 10px!important;
vertical-align: middle!important;
margin: 9px 9px 9px 0px!important;
}
.ztree li span.button.noline_close {
background: url(${ctx }/zTree/images/tree_open.png) no-repeat!important;
width: 10px!important;
height: 10px!important;
vertical-align: middle!important;
margin: 9px 9px 9px 0px!important;
}
.ztree li a span.button.ico_open {
background: url(${ctx }/zTree/images/tree_level2.png) no-repeat!important;
}
.ztree li a span.button.ico_close {
background: url(${ctx }/zTree/images/tree_level2.png) no-repeat!important;
}
.ztree>li>a>span.button.ico_open {
background: url(${ctx }/zTree/images/tree_level1.png) no-repeat!important;
}
.ztree>li>a>span.button.ico_close {
background: url(${ctx }/zTree/images/tree_level1.png) no-repeat!important;
}
.ztree li a span.button.ico_docu {
background: url(${ctx }/zTree/images/tree_level3.png) no-repeat!important;
}
.ztree *{
font-family: SimHei!important;
font-size: 18px!important;
color: #666666!important;
}
.ztree li a {
margin-bottom: 5px!important;
height: 28px!important;
line-height: 28px!important;
}
.ztree li a.curSelectedNode {
border: 1px solid #2983cf!important;
background: #d5ecf9!important;
}
.ztree li span.button {
height: 28px!important;
width: 20px!important;
line-height: 28px!important;
text-align: center;
vertical-align: middle!important;
}
.ztree>li{
margin-bottom: 4px!important;
}
.ztree ul {
padding-left: 28px!important;
}
.ztree li span.button.chk {
width: 13px!important;
height: 13px!important;
}
.ztree li span{
z-index: 1;
}
/*ztree-end*/

#container {
min-height: 800px;
position: relative;
border: 1px solid #666666;
background-color: #ffffff;
border-radius: 5px;
z-index: 0;
overflow: auto;
}
#container .model table {
border: 1px solid #ddd;
border-radius: 5px;
margin-bottom: 0;
}
#container .model table thead th{
background-color: #3E7E9C;
text-align: center;
background-image: none;
}
#container .model table tbody{
background-color: #CBEAE1;
}
.jtk-endpoint, .endpointTargetLabel, .endpointSourceLabel {
cursor: pointer;
}
</style></head><body><div class="container-fluid"><div class="row"><div class="col-xs-2" style="min-height: 800px;background-color: #84ACB3;border-radius:5px;padding-top: 12px;"><div class="content_wrap" style="width: 100%;"><div class="zTreeDemoBackground left" style="width: 100%;"><ul id="leftMenu" class="ztree" style="height: 800px;overflow: auto;width: 100%;"></ul></div></div></div><div class="col-xs-10"><div id="container"></div></div></div></div><div style="padding-top: 10px;">
模型名称:<input type="text" value='' id="modelName" style="height: 32px;margin-right:5px;"/>
模型描述:<input type="text" value='' id="modelDesc" style="height: 32px;margin-right:5px;"/><button class="btn btn-white btn-info" type="button" onclick="save()" style="display: inline-block;"><i class="ace-icon fa fa-check bigger-120 blue"></i> 保存</button></div><div id="myModal" class="modal fade" aria-labelledby="myModalLabel" aria-hidden="true"><div class="modal-dialog"><div class="modal-content"><div class="modal-header"><button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button><h4 class="modal-title" id="myModalLabel">请选择模型联系条件</h4></div><div class="modal-body">
连线类型:<select id="twoWay"><option value="false">单向</option><option value="true">双向</option></select>
条件:<select id="select_sourceList"></select><select id="select_comparison" ><option value="=" selected="selected">=</option></select><select id="select_targetList"></select></div><div class="modal-footer"><button id="submit_label" type="button" class="btn btn-primary" data-dismiss="modal">确定</button></div></div></div></div><!-- javascript --><script type="text/javascript" src="${ctx }/js/model/addModel.js"></script><script type="text/javascript">
$(document).ready(function(){

getDataSet("${ctx }/ajaxGetDataSet.do");

//监听新的连接
instance.bind("connection", function (connInfo, originalEvent) {
init(connInfo.connection);
});
// listen for clicks on connections, and offer to delete connections on click.
instance.bind("dblclick", function (conn, originalEvent) {
if (confirm("要删除从 " + conn.source.getElementsByTagName("th")[0].innerHTML
+ " 到 " + conn.target.getElementsByTagName("th")[0].innerHTML + " 的连接么?")){
instance.detach(conn);
}
});
});
function save(){
//下面两个只是到后台执行相关业务逻辑的链接,在后面的js中会用到,所以弄了一个变量,传到saveToDb方法中
var ajaxToVerifySql = "这里只是一个异步保存并执行所产生的SQL语句的链接";
var ajaxToSaveModel = "这个是保存模型相关数据的链接";
//保存到数据库
saveToDb(ajaxToVerifySql,ajaxToSaveModel);
}
</script></body></html>