/**
* version:0.1
* 2020/12/18
* author:fanjiantao (abbe)
*/
!(function(name, factory) {
try {
if ($) {}
} catch (error) {
console.warn(error + "【本项目需要依赖jquery库】");
return
}
if (typeof exports === 'object') {
module.exports = factory();
} else if (typeof define === 'function' && define.amd) {
define(factory);
} else {
window[name] = factory();
}
})("OkrTree", function() {
/**模板区域**/
var namespace = "OkrTree",
dataArray = [],
tagCalback = null,
itemCallback = null,
isdrop = true,
dropDom = "", //当前正在拖动的dom
//带有子节点的需要这条dom树
lineDom = "
",
//左叶子树需要
lineTop = function(left, right) {
return "");
},
// lineTop = "",
// leftDom = "",
// rightDom = "",
leftDom = "",
rightDom = "",
tagBox = function(data, path, last) {
// console.log(last)
return '' + (last ? '
' : '') + '
' + (tagCalback && tagCalback(data, path)) + '
'
},
expandBox = "-
",
itemTemplate = function(data, path) {
if (itemCallback) { return itemCallback(data, path) };
return ""
};
/**core code----------------------------------------------------------------------------------------------------------------**/
function buildNode(data) {
var template = function(data, vip, root, path, tag_index, zType) {
var s = "",
len = data.length,
parent = path || "";
$.each(data, function(index, item) {
var path = "",
tag = "",
zr = "",
lastTag = item.children instanceof Array && item.children.length == 1 && item.children[0].type == "tag";
tagIndex = 0;
if (!parent) {
path = index + "";
} else {
path = parent + '-' + index;
}
/* 处理tag标记*/
item.children && $.each(item.children, function(index, item1) {
if (item1.type && item1.type == "tag") {
tag = tagBox(item1, path + '-' + index, lastTag);
if (item.children.length > 1 && index == 0) {
tagIndex = 1;
zr = "left";
} else {
(item.children.length - 1 == index) && (tagIndex = item.children.length - 2, zr = "right")
}
}
})
if (item.type && item.type == "tag") return;
s += "").concat(root ? '' : lineTop(index == 0 && !root || index == tag_index && zType == 'left', index == len - 1 || index == tag_index && zType == 'right'), "
").concat(itemTemplate(item, path), "
").concat(item.children && item.children.length > 0 && expandBox || "").concat(tag).concat(item.children && item.children.length > 0 ? "".concat(tag == "" ? lineDom : "", "
").concat(template(item.children, item.children.length == 1, false, parent + (parent && "-") + index, tagIndex, zr), "
") : '', "
");
//s += `${root?'':lineTop((index==0&&!root||(index==tag_index&&zType=='left')),(index==len-1||(index==tag_index&&zType=='right')))}
${itemTemplate(item,path)}
${item.children&&item.children.length>0&&expandBox||""}${tag}${(item.children&& item.children.length > 0)?`${tag==""?lineDom:""}
${template(item.children,item.children.length==1,false,parent+(parent&&"-")+index,tagIndex,zr)}
`:''}
`;
})
return s;
};
return "" + template(data, false, true) + "
";
}
/**局部处理tag标记**/
function reverseObject(object) {
/**反转对象**/
var newObject = {};
var keys = [];
for (var key in object) {
keys.push(key);
}
for (var i = keys.length - 1; i >= 0; i--) {
var value = object[keys[i]];
newObject[keys[i]] = value;
}
return newObject;
}
function renderTagBox(contentWidth) {
// $("." + namespace + " .tagBox").each(function(index, item) {
// var tagContent = tagBox.find(".tagContent");
// var contentWidth = tagContent.outerWidth();
// tagBox.css({
// width: (contentWidth+50)*2 + "px"
// });
// })
}
function renderLayout() {
//待处理偏移量的元素;
var walkList = [];
//1.先处理宽度问题
$("." + namespace + " .tagBox").each(function(index, item) {
// var tagWidth = 170;
var tagBox = $(item);
var tagBoxwidth = $(item).outerWidth();
var row = tagBox.siblings('.row');
var tagContent = tagBox.find(".tagContent");
var contentHeight = tagContent.outerHeight();
var contentWidth = tagContent.outerWidth();
tagBox.css({
height: contentHeight + 82 + "px",
})
tagContent.css({
marginTop: -(contentHeight / 2) + "px"
})
if (tagBoxwidth / 2 > (contentWidth + 50)) {
return
}
tagBox.css({
width: (contentWidth + 50) * 2 + "px"
});
//把暂存区元素注入队列,后续处理
walkList.push({
tag: tagBox,
row: row, //row 元素
items: row.children(".item") //子元素,
});
})
$.each(walkList.reverse(), function(index, item) {
function sumWidth(arr) {
var s = 0;
for (var i = arr.length - 1; i >= 0; i--) {
s += $(arr[i]).outerWidth();
}
return s;
}
var diff = item.row.outerWidth() - (sumWidth(item.items));
if (diff > 0) {
item.row.css({
'paddingLeft': diff / 2 + "px"
});
} else {
item.tag.css({
width: "auto"
})
}
item.items.length == 1 && item.tag.children('div').css({
'borderBottom': 'none'
});
})
walkList = null;
}
function initEvent() {
$(document.body).on('click', "div.expandIcon", function() {
var parent = $(this).parent();
if (parent.hasClass("expand")) {
parent.removeClass("expand");
$(this).nextAll().css({
visibility: '',
// display: ''
}).end().text("-").attr("title", "折叠");
} else {
parent.addClass("expand");
$(this).nextAll().css({
visibility: 'hidden',
// display: "none"
}).end().text("+").attr('title', "展开");
}
renderLayout()
});
if (!isdrop) return;
// $(document).on("dragstart", function(e) {
// var e = e || window.event
// if (e.target.tagName == "IMG") {
// };
// })
$("." + namespace).on('dragstart', '.template', function(e) {
dropDom = $(this);
dropDom && $("#orgTree .template").not(dropDom && dropDom.parent().parent().find(".template")).css({
border: "dashed 1px black"
});
});
$("." + namespace).on('dragover', ".template", function(e) {
var e = e || window.event
e.preventDefault();
if ($(this)[0] !== dropDom[0]) {
$(this).not(dropDom.parent().parent().find(".template")).css({
border: "dashed 1px red"
})
}
});
$("." + namespace).on('dragleave', ".template", function(e) {
dropDom && $("#orgTree .template").not(dropDom && dropDom.parent().parent().find(".template")).css({
border: "dashed 1px black"
});
});
$("." + namespace).on('drop', '.template', function(e) {
var e = e || window.event
e.preventDefault();
var to = $(this).parent().parent()[0],
form = dropDom.parent().parent()[0];
if ($.contains(form, to) || dropDom[0] == $(this)[0]) {
// console.log('不能执行自己的拖拽逻辑')
} else {
walkData($(to).attr('data-path'), $(form).attr("data-path"));
}
})
$("." + namespace).on('dragend', function(e) {
$("." + namespace + " .template").css({
border: ""
});
})
}
/**拖拽节点后处理布局**/
function walkData(toPath, formPath) {
var formPatharrray = formPath.split("-");
var toData = new Function("dataArray", "return dataArray" + "[" + toPath.split("-").join("].children[") + "]")(dataArray);
var formData = new Function("dataArray", "return dataArray" + "[" + formPath.split("-").join("].children[") + "]")(dataArray);
var popIndex = formPatharrray.pop();
var formParent = new Function("dataArray", "return dataArray" + "[" + formPatharrray.join("].children[") + "]")(dataArray);
if (toData.children) {
toData.children.push(formData);
formParent.children.splice(popIndex, 1);
} else {
toData.children = [formData];
formParent.children.splice(popIndex, 1);
}
formParent.children.length == 0 && (formParent.children = "")
$("." + namespace).html(buildNode(dataArray)); // 插入模板
renderLayout(); // 渲染布局
}
function init() {
$("." + namespace).html(buildNode(dataArray)); // 插入模板
renderLayout(); // 渲染布局
initEvent(); // 注册事件
}
$.fn[namespace] = function(options) {
var defaults = {
version: "1.0",
isdrop: true,
data: [],
css: {
lineColor: "black",
background: "#fff"
},
style: document.createElement('style'),
},
opts = $.extend({}, defaults, options),
style = ".OkrTree .row {zoom: 1}.OkrTree .row::after {content: \" \";display: block;clear: both}.OkrTree .item {display: table-cell;position: relative;text-align: center;vertical-align: top;}.OkrTree .line {margin: auto;height: 20px}.OkrTree .line .left {width: 50%;height: 100%;float: left;box-sizing: border-box;border-right: solid 1px ".concat(opts.css.lineColor, ";}.OkrTree .line .right {width: 50%;height: 100%;float: left;box-sizing: border-box;border-left: solid 1px ").concat(opts.css.lineColor, ";}.OkrTree .row .item:first-child {margin-left: 0}.OkrTree .content {text-align: center;margin: auto;box-sizing: border-box;padding: 0 10px;border-radius: 4px;white-space: normal}.OkrTree .content>.template {width: auto;margin: auto;display: inline-block;border-radius: 4px;word-break: break-all;white-space: pre-wrap}.OkrTree .lineTop {height: 20px;margin: auto;position: relative;}.OkrTree .lineTop>.line-left {width: 50%;position: absolute;box-sizing: border-box;height: 100%;border-right: solid 1px ").concat(opts.css.lineColor, ";}.OkrTree .lineTop>.line-left.top {border-top: solid 2px ").concat(opts.css.lineColor, ";}.OkrTree .lineTop>.line-right.top {border-top: solid 2px ").concat(opts.css.lineColor, ";}.OkrTree .lineTop>.line-right {position: absolute;left: 50%;box-sizing: border-box;width: 50%;border-left: solid 1px ").concat(opts.css.lineColor, ";height: 100%;}.OkrTree .tagBox {overflow: hidden;min-height: 50px;box-sizing: border-box}.OkrTree .tagBox>div {float: left;width: 50%;height: 100%;box-sizing: border-box;}.OkrTree .tagBox div.tagLeft {border-right: solid 1px ").concat(opts.css.lineColor, ";position: relative}.OkrTree .tagBox>.tagDownLine {width: 0px;border-right: 2px solid ").concat(opts.css.lineColor, ";position: absolute;left: 50%;margin-left: -1px;height: 50%}.OkrTree .tagBox div.tagRight {border-left: solid 1px ").concat(opts.css.lineColor, ";position: relative}.OkrTree .tagBox div.tagRight>.line {width: 50px;height: 0;top: 50%;margin-top: -1px;border-bottom: solid 2px ").concat(opts.css.lineColor, ";position: absolute}.OkrTree .tagContent {position: absolute;top: 50%;left: 50px;width: auto;text-align: center;border-radius: 4px;}.OkrTree .tagBox div.tagRight .tagItem {height: 40px;background-color: green;position: absolute;right: 0;top: 50%;margin-top: -20px;border-radius: 2px;color: #fff;text-align: center;line-height: 40px}.OkrTree .expandIcon {display: inline-block;width: 20px;height: 20px;background-color: ").concat(opts.css.lineColor, ";color: #fff;font-size: 100%;line-height: 20px;text-align: center;border-radius: 50%;cursor: pointer;font-weight: bold}.OkrTree .template {border: solid 1px transparent;}");;
this.addClass(namespace);
opts.style.innerHTML = style;
document.getElementsByTagName('head')[0].appendChild(opts.style);
dataArray = opts.data instanceof Array && opts.data;
typeof opts.itemTemplate == 'function' && (itemCallback = opts.itemTemplate);
typeof opts.tagTemplate == 'function' && (tagCalback = opts.tagTemplate);
typeof opts.isdrop == 'boolean' && (isdrop = opts.isdrop);
init();
return opts;
}
})