웹 UI 라이브러리인 GWC에서 제공하는 Tree 컴포넌트에 대한 예제 코드입니다.
먼저 DOM 구성은 다음과 같습니다.
그리고 CSS 구성은 다음과 같구요.
.center { display: flex; width: 100%; height: 100%; justify-content: center; align-items: center; flex-direction: column; gap: 1em; } gwc-vscrollview { width: 22em; height: 30em; background: rgba(0,0,0,0.3); border: 1px solid black; } gwc-tree { width: 100%; padding: 0.5em 0.5em; } .h-center { display: fex; justify-content: center; align-items: center; }
js 코드는 다음과 같습니다.
window.onload = () => { // 최상위 폴더(root) const rootFolder = tree.rootFolder; // 폴더 추가 const gaFolder = rootFolder.addFolder("아카이브"); const docFolder = rootFolder.addFolder("문서").open(); rootFolder.addFolder("프로그램"); const programFolder = rootFolder.getFolder("프로그램"); const humanGeoFolder = gaFolder.addFolder("인문공간데이터"); const adminGeoFolder = gaFolder.addFolder("행정경계"); // 폴더에 파일 추가 humanGeoFolder.addFile("인구통계.zip", "url(../examples/images/icon7.png)"); humanGeoFolder.addFile("유동인구.zip", "url(../examples/images/icon7.png)"); humanGeoFolder.addFile("유아통계.zip", "url(../examples/images/icon7.png)"); const koreaFolder = adminGeoFolder.addFolder("대한민국"); koreaFolder.addFile("시도.zip", "url(../examples/images/icon3.png)"); koreaFolder.addFile("시군구.zip", "url(../examples/images/icon3.png)"); koreaFolder.addFile("읍면동.zip", "url(../examples/images/icon3.png)"); adminGeoFolder.addFile("서울특별시.zip", "url(../examples/images/icon3.png)"); adminGeoFolder.addFile("경기도.zip", "url(../examples/images/icon3.png)"); docFolder.addFile("레포트1.pdf", "url(../examples/images/icon6.png)"); docFolder.addFile("레포트2.pdf", "url(../examples/images/icon6.png)"); docFolder.addFile("레포트3.pdf", "url(../examples/images/icon6.png)"); programFolder.addFile("VisualSudio.Code.zip", "url(../examples/images/icon5.png)") programFolder.addFile("PhotoShop.zip", "url(../examples/images/icon5.png)") programFolder.addFile("리터널_PS5.zip", "url(../examples/images/icon5.png)") // 폴더 열고 닫기 btnProgramOpenClose.addEventListener("click", () => { const folder = tree.rootFolder.getFolder("아카이브"); if(folder.isOpen()) folder.close(); else folder.open(); }); // 특정 폴더에 파일 추가 btnAddFile.addEventListener("click", () => { const folder = tree.rootFolder.getFolder("문서"); const file = folder.getFile("NEW 레포트.pdf"); if(file) { file.remove(); } else { const file = folder.addFile("NEW 레포트.pdf", "url(../examples/images/icon6.png)"); // 파일 또는 폴더에 사용자 정의 데이터 추가 file.setData("생성일자", "2022년 2월 10일"); console.log(file.getData("생성일자")); } }); // 파일(폴더+파일)에 대한 클릭 이벤트 tree.addEventListener("fileClick", (event) => { const file = event.detail.file; const parentFolderName = file.parentFolder.name; const bFolder = file.isFolder(); const bOpen = file.isOpen(); label.content = ` 이름: ${file.name} 부모폴더: ${parentFolderName?parentFolderName:"없음"} 종류: ${bFolder?"폴더":"파일"} ${bFolder?`상태: ${bOpen?"열림":"닫힘"}`:""} `; vscrollview.refresh(); // 폴더 열기로 인한 트리 컴포넌트 크기 변경에 따른 스크롤뷰 업데이트 }); // 트리 컴포넌트의 크기가 가변이므로 스크롤뷰를 업데이트 해줌 vscrollview.refresh(); GeoServiceWebComponentManager.instance.update(); };
실행 결과는 다음과 같습니다.
트리의 항목에 대한 팝업 메뉴 기능을 적용할 때에 대한 코드입니다.
// PopupMenu 생성 시작 const popupMenu = gwcCreatePopupMenu(); popupMenu.addMenuItem("menu1", { text: "생성", _icon: "images/icon1.png", onClick: (menuId) => { gwcMessage(`폴더 생성(${menuId})`); popupMenu.hide(); } }); popupMenu.addMenuItem("menu2", { text: "이름 변경", _icon: "images/icon2.png", onClick: (menuId) => { gwcMessage(`${popupMenu.fileData.name} 이름 변경(${menuId})`); popupMenu.hide(); } }); popupMenu.addMenuItem("menu3", { text: "삭제", _icon: "images/icon3.png", onClick: (menuId) => { gwcMessage(`${popupMenu.fileData.name} 삭제(${menuId})`); popupMenu.hide(); } }); popupMenu.addMenuItem("menu4", { text: "잘라내기", _icon: "images/icon4.png", onClick: (menuId) => { gwcMessage(`${popupMenu.fileData.name} 잘라내기(${menuId})`); popupMenu.hide(); } }); popupMenu.addMenuItem("menu5", { text: "붙여넣기", _icon: "images/icon5.png", onClick: (menuId) => { gwcMessage(`${popupMenu.fileData.name}에 붙여넣기(${menuId})`); popupMenu.hide(); } }); // PopupMenu 생성 완료 // 파일(폴더+파일)에 대한 클릭 이벤트 tree.addEventListener("fileClick", (event) => { const file = event.detail.file; const contextMenu = event.detail.contextMenu; if(contextMenu) { console.log(event.detail.originalEvent); popupMenu.fileData = file; // fileData는 임의로 부여한 속성으로 팝업 메뉴 실행 시에 참조됨 popupMenu.show(event.detail.originalEvent.clientX, event.detail.originalEvent.clientY); } });
위의 코드에 대한 실행 결과는 다음과 같습니다.
트리를 구성하는 항목에 대해서 선택된 항목이라는 피드백을 줄 수 있습니다. 다음 코드를 참고하기 바랍니다.
tree.clearSelection(); // 일단 기존의 선택된 항목에 대해 선택 해제 tree.rootFolder.getFolder("아카이브").selected = true; // 폴더를 얻고 해당 폴더를 선택된 상태로 표시
폴더 또는 파일 항목의 우측에 Tag 정보를 표시할 수 있습니다. 즉, getFolder 또는 getFile을 통해 얻은 item 객체의 tag 속성(get, set)을 설정하면 됩니다. 아래는 파일항목의 우측에 파일의 크기를 표시하는 예시입니다.
tree 컴포넌트는 동일한 계층에 동일한 이름을 가진 항목을 추가할 수 없습니다. 이때 label 속성을 이용해 이름은 다르지만 표시되는 제목만을 변경해 줄 수 있습니다. 코드 예시는 다음과 같습니다.
data.forEach(item => { const rootFolder = this.#tree.rootFolder; rootFolder.addFile(item.id, "url(../images/layers.svg)").label = item.title; });