개요
안녕하세요 빈코입니다! 오늘은 지난번에 포스팅한 jstree 핸들링 방법 중 이전 선택 값이 남아있던 오류 해결에 이어서 상,하위 노드를 입맛대로 선택하는 방법에 대해 포스팅하려고 합니다😃
제가 해결해야 했던 과제중에, jstree를 사용하는 조직도 안에서 상위 노드를 선택했을 경우에는 하위 노드가 자동으로 선택되게 하고, 하위노드를 모두 선택했을 때는 jstree 내부적으로 상위 노드까지 선택되어지는 기능은 꺼야하는 상황이였습니다. 이론상으로는 막막했지만 해결과정은 생각보다 간단합니다 :)
그럼 jstree의 내부 동작에 대해 알아볼까요?
jstree 기본 기능📙
jstree에서 제공하는 기본 기능중에 'three-state' 옵션은 상, 하위 노드간의 연결 관계를 의미하는데, 기본적으로 true로 설정되어 있어서 상위 노드를 선택하면 자동적으로 하위 노드까지 선택되는 기능입니다. 또한, 하위 노드가 모두 선택되면 자동적으로 상위 노드까지 선택됩니다. 이 모든 것이 'three-state' 옵션이 true로 기본값으로 설정되어 있기 때문입니다.
// Example
$("#tree").jstree({
plugins: ["wholerow","checkbox","types","search","sort","changed"],
checkbox: {
"cascade_to_disabled": false,
"three_state": true // true 기본값
},
core: {
themes: { responsive: !1 },
dblclick_toggle: false,
data: data
},
sort: function (a, b) {
a1 = this.get_node(a);
b1 = this.get_node(b);
if (a1.icon != b1.icon) {
return a1.icon > b1.icon ? -1 : 1;
}
},
types: {
default: { icon: "fa fa-folder icon_state-warning icon_lg" },
}
});
반대로, 'three-state' 옵션을 false로 지정했을 경우에는 상, 하위 노드가 아무런 관계가 없어집니다. 즉, 부모-자식간의 관계가 사라져 상,하위 노드 개념이 아닌 각각의 노드의 개념으로 바뀐다고 생각하시면 됩니다.
사실 요구사항이 '상위 노드를 선택해도 하위 노드는 선택되지 말고, 똑같이 하위 노드 모두가 선택되도 상위 노드는 선택되지 말아야 한다' 였으면 간단히 해당 옵션을 꺼주면 됐던 과제였습니다. 하지만 그렇지 않죠..^^
이렇기에 우리는 jstree 내부를 뜯어봐야 합니다😂
jstree.min.js📘
jstree에서는 jstree.min.js를 제공합니다. 많은 개발자들이 jstree 공식 문서에서 jstree.min.js를 다운받고 아래와 같이 import해서 사용합니다.
<script src="dist/jstree.min.js"></script>
하지만 min.js이기 때문에 코드가 아래 사진과 같이 모두 한줄로 정렬되어 있기 때문에, 코드를 고치기에는 많이 힘들죠😅
그래서 저희는 js.beautify 웹사이트에서 제공하는 기능을 통해 jstree.min.js를 보기 쉽게 변경해줘야 합니다.
변경을 완료하셨으면 해당 코드를 원하는 이름으로 js를 생성해주시면 됩니다. 저는 여러 테스트를 진행하면서 custom이라는 이름을 붙혀 아래와 같이 파일을 구성했습니다.
jstree 내부동작📒
변경된 코드를 보면 아시겠지만, 오픈소스는 처음 봤을 때 정말 외계어입니다.. 그래도 계속 보다보면 해당 코드들이 어떤 기능을 하는지 대강 보일거에요:) 어차피 지금 상황에서의 핵심은 '상위 노드 선택 시 하위 노드는 자동 선택, 하위 노드 모두 선택 시 상위 노드는 미선택!!'
코드를 쭉 따라 내려가시다 보면 아래 코드를 만나시게 될거에요
if (-1 !== n.indexOf("down"))
if (e.state[o ? "selected" : "checked"]) {
for (i = 0, j = f.length; j > i; i++) d[f[i]].state[o ? "selected" : "checked"] = !0;
this._data[o ? "core" : "checkbox"].selected = this._data[o ? "core" : "checkbox"].selected.concat(f)
} else
for (i = 0, j = f.length; j > i; i++)
if (d[f[i]].state[o ? "selected" : "checked"]) {
for (k = 0, l = d[f[i]].children_d.length; l > k; k++) d[d[f[i]].children_d[k]].state[o ? "selected" : "checked"] = !0;
this._data[o ? "core" : "checkbox"].selected = this._data[o ? "core" : "checkbox"].selected.concat(d[f[i]].children_d)
}
if (-1 !== n.indexOf("up")) {
for (i = 0, j = e.children_d.length; j > i; i++) d[e.children_d[i]].children.length || g.push(d[e.children_d[i]].parent);
for (g = a.vakata.array_unique(g), k = 0, l = g.length; l > k; k++) {
e = d[g[k]];
while (e && e.id !== a.jstree.root) {
for (h = 0, i = 0, j = e.children.length; j > i; i++) h += d[e.children[i]].state[o ? "selected" : "checked"];
if (h !== j) break;
e.state[o ? "selected" : "checked"] = !0, this._data[o ? "core" : "checkbox"].selected.push(e.id),
m = this.get_node(e, !0), m
&& m.length && m.attr("aria-selected", !0).children(".jstree-anchor").addClass(o ? "jstree-clicked" : "jstree-checked"),
e = this.get_node(e.parent)
}
}
if 조건문 내용을 보면 뭔가 느낌이 오시지 않나요? 첫 번째 조건문은 'down' 즉 상위 노드를 선택했을 때 하위 노드도 선택할지에 대한 조건들이 명시되어 있고, 두번째 조건문은 'up' 즉 하위 노드들이 모두 선택되었을 때, 상위 노드를 선택할지에 대한 내용입니다.
우리의 요구사항은 '하위 노드를 모두 선택했을 때만 상위 노드가 선택되는 것을 막는다'이기 때문에, 두번째 조건문 'up' 관련 코드를 주석처리하여 과제를 해결하면 됩니다😊
사실, 과제중에 '하위 노드를 모두 선택했을 때 상위 노드를 선택할 것이냐는 알림창 기능'도 있는데, 해당 기능은 확인을 눌렀을 때는 상위 노드가 선택되게 하고, 취소를 눌렀을 때는 선택한 하위노드들만 선택되게 하는 기능도 있었습니다. 혹시나 이런 기능까지 구현해야 하신다면 댓글 달아주세요! 이 부분도 상당히 쉽게 해결할 수 있기 때문에 답글로 설명 드리겠습니다 :)
마치며
지금까지 jstree 핸들링 방법 중 상,하위 노드를 입맛대로 선택하는 방법에 대해 알아보았습니다. 다음 포스팅의 주제는 만약 tree가 대용량 데이터이고, 해당 tree를 불러올 때 선택되어 있는 노드가 많은 상태라면 행(hang)이 걸리는 상황에 대한 해결방법입니다😁
👨👩👦👦 오픈채팅방 운영
취업을 준비하는 예비 개발자분들을 위한 질문&답변할 수 있는 공간을 만들었습니다. 취업과 이직을 하기 위해서 어떤 걸 중점적으로 준비해야 하는지부터 포트폴리오&이력서 작성법 등 다양한 질문들을 받고 답변을 드립니다. 참여하셔서 다양한 정보 얻고 가시면 좋을 것 같네요😁
참여코드 : 456456
https://open.kakao.com/o/gVHZP8dg
👨💻 전자책 출간
아울러 제가 🌟비전공자에서 2년만에 보안 전문 중견기업으로 이직 한 방법들을 정리한 전자책을 출간 하게 되었습니다. 어떤 걸 공부해야 하는지, 이직을 위해서 무엇을 준비해야 하는지, 제가 받았던 기술 면접 리스트 등 다양한 목차로 구성되어 있습니다. 또한, 구매 시 1:1 채팅을 이용하여 포트폴리오 첨삭을 도와드리고 있습니다. 🐕전자책으로 얻은 모든 수익은 유기견 센터 '팅*벨 입양센터'에 후원될 예정입니다. 관심 있으신 분들은 아래 링크를 참고해주세요😁
관련 포스팅
'TIL' 카테고리의 다른 글
Java 날짜 함수 DateUtil 모음집 (2) | 2024.03.27 |
---|---|
jstree 핸들링 방법(대용량 데이터 다루기 - 행걸리는 현상) (0) | 2024.03.07 |
Java 대용량 데이터 HashSet 기본개념 및 사용법(예시) (2) | 2024.02.08 |
Java 대용량 데이터 HashMap 기본개념 및 시간복잡도(예시) (0) | 2024.02.02 |
Java 대용량 데이터 이중반복문 vs 배열 사용 속도차이(예시) (4) | 2024.01.24 |