jsTree는 jquery 기반으로, HTML 또는 JSON 데이터를 Tree 콘트롤로 웹에 출력해 주는 자바스트립트 라이브러리이다.
홈페이지는 이곳 ==> https://www.jstree.com/
사용한 예는 다음과 같다.
먼저 jsTree 라이브러리를 불러온다.
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.3.2/themes/default/style.min.css" /> <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.3.2/jstree.min.js"></script> <!-- (...중략...) --> <div id="layerTree"></div>
이후 HTML 또는 JSON 데이터를 생성해 jstree()를 실행시킨다.
// jsTree 생성 $('#layerTree').jstree({ "plugins" : [ "wholerow", "checkbox", "changed" ], 'core' : { 'data' : treeJson } });
데이터 정의는 HTML과 JSON 두가지가 있는데, 위 코드는 JSON 방식이다.
HTML의 경우, ‘ul’과 ‘li’ 태그를 이용하여 계층을 표현한다.
예제를 따라서, 구현을 들어갔는데 HTML 출력이 원하는대로 되지 않아서, JSON 방식으로 구현했다.
오히려 더 깔끔하고, Tree 자료구조 그대로 삽입할 수 있어서 더 나은 선택이 되었다.
** JSON 자료구조
참고: https://www.jstree.com/docs/json/
// jsTree의 Node 자료구조 { id : "string" // will be autogenerated if omitted text : "string" // node text icon : "string" // string for custom state : { opened : boolean // is the node open disabled : boolean // is the node disabled selected : boolean // is the node selected }, children : [] // array of strings or objects li_attr : {} // attributes for the generated LI node a_attr : {} // attributes for the generated A node } // jsTree 사용예 $('#using_json').jstree({ 'core' : { 'data' : [ 'Simple root node', // 단독으로 text만 넣거나 { // 자료구조를 지켜서 넣거나 'text' : 'Root node 2', 'state' : { 'opened' : true, 'selected' : true }, 'children' : [ // 자식노드들은 Array에 넣어야 한다 { 'text' : 'Child 1' }, 'Child 2' ] } ] } });
이를 위해 사용자가 정의한 데이터로부터 jsTree와 호환되는 Tree 자료구조를 구현해야 하는데
다음과 같이 코드를 작성하였다.
/** ** **************************************************** ** 레이어 리스트 Tree 생성 ** **************************************************** */ var treeCtrl = treeCtrl || (function(){ var Node = function( nodeName ){ return { text: nodeName, state: { 'opened' : false, 'selected' : false }, data: null, // @type: ol.Layer children: [] }; }; var _root = new Node('ROOT','group'); var findChild = function( parent, nodeName ){ for( var i=0; i<parent.children.length; i++ ){ var child = parent.children[i]; if( child.text == nodeName ){ return child; } } return null; }; // find parent which save item var getParent = function( parent, group, opt_make ){ opt_make = ( typeof opt_make === 'undefined' ) ? true : false; for( var i=0; i<group.length; i++ ){ var child = findChild( parent, group[i] ); // 없으면 Node 생성 if( !child ){ if( !opt_make ) return null; child = new Node( group[i] ); parent.children.push( child ); } parent = child; } return parent; } // group에 layer 아이템 저장 var _set = function( key, item ){ var group = key.split('-'); var parent = getParent( _root, group ); var child = new Node( item.name, 'item' ); child.data = item; parent.children.push( child ); return child; }; // item인 node들만 반환 (=layer) var _get = function( key ){ var group = key.split('-'); var parent = getParent( _root, group ); return parent.children.filter(function( node ){ return node.type == 'item' }); }; var _clear = function(){ _root.children = []; }; var _setState = function( key, state ){ var group = key.split('-'); var node = getParent( _root, group, false ); if( !node ) return false; node['state'] = state; return true; }; var _toTreeJson = function(){ return _root.children; }; return { 'root' : _root, 'set' : _set, 'get' : _get, 'setState' : _setState, 'toTreeJson': _toTreeJson, 'clear' : _clear, }; })(treeCtrl); // wfsData 읽어들이기 for( var key in wfsData ){ var node = treeCtrl.set( wfsData[key].group, wfsData[key] ); } // 법정경계 펼치고, 선택하기 treeCtrl.setState( '주제도-법정경계', { 'opened' : true, 'selected' : true } ); var treeJson = treeCtrl.toTreeJson(); //console.log( treeJson );
Node의 트리 위치는 set() 함수의 ‘key’로 정의되는데, ‘-‘ 분리자로 계층을 표현하였다.
예를 들어, ‘주제도-법정경계’라면 ‘주제도’ 아래에 ‘법정경계’ 노드를 가리킨다.
이에 대한 트리 생성과 이벤트 처리는 다음과 같이 한다.
** 생성 옵션: “wholerow”, “checkbox”, “changed”
** 이벤트 : ‘changed’에 대해 ‘selected’와 ‘deselected’를 처리
// jsTree 생성 $('#layerTree').jstree({ "plugins" : [ "wholerow", "checkbox", "changed" ], 'core' : { 'data' : treeJson } }); // jsTree 클릭 이벤트 : 레이어 setVisible $('#layerTree').on("changed.jstree", function (e, data) { // 선택된 레이어 보이기 var i, j, r = []; for(i = 0, j = data.changed.selected.length; i < j; i++) { var node = data.instance.get_node( data.changed.selected[i] ); if( node.data !== null && node.data.hasOwnProperty('layer') ){ wfsLayers[ node.data.layer ].setVisible( true ); r.push( node.data.layer ); } } console.log( 'selected Layer: ' + r.join(', ') ); // 선택해제된 레이어 감추기 r = []; for(i = 0, j = data.changed.deselected.length; i < j; i++) { var node = data.instance.get_node( data.changed.deselected[i] ); if( node.data !== null && node.data.hasOwnProperty('layer') ){ wfsLayers[ node.data.layer ].setVisible( false ); r.push( node.data.layer ); } } console.log( 'deselected Layer: ' + r.join(', ') ); });
jsTree 선택에 의한 조작 대상은 OpenLayer3의 layer의 setVisible() 이다.
더 자세한 설정은 jsTree 홈페이지를 참조하시길..
구글링으로도 예제코드들이 잘 나온다. (마음에 드는게 안나와서 기록하는 거지만)
안녕하세요 혹시 jsTree 에서 폴더 위치 변경도 사용가능한가요? 궁금해서.ㅠ
좋아요좋아요