WEB/JavaScript
[JavaScript] TreeView 사용하기 (fancytree)
S0PH1A
2019. 6. 3. 17:44
반응형
[JavaScript] TreeView 사용하기 (fancytree)
사용하고자 하는 Tree 조건은 다음과 같았다.
* Tree(트리) 사용 조건
- 방향키로 노드간 이동 가능해야 한다.
- shift, ctrl이용해서 다중 선택이 가능해야 한다.
- 폴더간 드래그 앤 드롭으로 이동이 가능해야 한다.
- 루트 노드는 이동 불가해야 한다.
- 자식노드는 자식노드 하위로 이동 불가해야 한다.
위 조건을 모두 만족하는 트리를 찾기 힘들었다.
처음에는 가장 많이 쓰는 라이브러리를 찾아 구현되어 있지 않는 조건들은 stackoverflow 나 git 등에서 찾아 기능을 추가하려고 했으나, 쉽지 않았다.
완성된 프로젝트에 트리 부분만 떼다 붙이려니 여러가지 오류가 발생했었다.
-
jstree
- 가장 많이 사용함.
- 위 조건 모두 구현 가능함.
- 하지만, Electron에서 코드를 삽입하니 jstree() 를 찾을 수 없다는 오류만 뜸....
-
jqtree
- 사용이 간단함.
- shift, ctrl 기능이 없음.
- 다중 선택은 되나, 불편함. ( 다중 선택하여 노드 이동이 안됨 )
- shift, ctrl 를 이용하여 다중 선택까진 구현했으나,
부모가 다른 자식을 선택할 경우와 다중 선택한 파일을 이동시키는 부분에서 막힘....
-
fancytree
- jqtree보단 많이 사용하는 듯 함.
- 위 모든 조건 다 만족하는 엄청나게 많은 기능을 제공함.
- 루프 노드 이동을 막는 코드는 구글에 많이 존재했지만, 자식 노드 하위로 이동을 막는 부분을 찾기 힘들었다.
- 하지만, 모든 조건에 맞게 구현이 가능했다.
# fancytree
-
설치
$ npm install jquery.fancytree --save
-
사용
- Electron에서는 CreateTree 옵션을 이용해서 fancytree를 생성할 수 있다.
- dragEnter에 조건에 원하는 조건을 추가해 줬다.
<!-- HTML -->
<!-- fancytree -->
<link href="../node_modules/jquery.fancytree/dist/skin-win8/ui.fancytree.min.css" rel="stylesheet">
<div id="tree"></div>
// JavaScript
const fancytree = require('jquery.fancytree');
// 필요한 모듈을 취사선택해서 추가한다.
require('jquery.fancytree/dist/modules/jquery.fancytree.ui-deps');
require('jquery.fancytree/dist/modules/jquery.fancytree');
require('jquery.fancytree/dist/modules/jquery.fancytree.dnd5');
require('jquery.fancytree/dist/modules/jquery.fancytree.multi');
// 선언
const _tree = fancytree.createTree('#tree', {
extensions: ["dnd5", "multi"],
checkbox: true,
selectMode: 3,
source: [],
activate: function (event, data) {},
lazyLoad: function (event, data) {
// data.result = {url: "ajax-sub2.json"}
},
dnd5: {
preventSameParent: false, // Prevent dropping nodes under the same direct parent
autoExpandMS: 1000,
refreshPositions: true,
multiSource: true, // drag all selected nodes (plus current node)
dragStart: function (node, data) {
// 루트 노드 이동 방지
if (node.isFolder() || node.getLevel() === 1) {
return false;
}
return true;
},
dragEnter: function (node, data) {
if (data.node.parent.parent === null) { // 부모 노드는 over만 가능
return ["over"];
} else { // 자식 노드 끼리는 over불가능(위치 변경만 가능)
return ["before", "after"]
}
},
dragOver: function (node, data) {
// data.node.info("dragOver", data);
return true;
},
dragEnd: function (node, data) {
data.node.info("dragEnd", data);
},
dragDrop: function (node, data) {
var sourceNodes = data.otherNodeList;
$.each(sourceNodes, function (i, o) {
o.info("move to " + node + ": " + data.hitMode);
o.moveTo(node, data.hitMode);
});
node.debug("drop", data);
node.setExpanded();
}
}
});
반응형