001002003004005006007008009010011012013014015016017018019020021022023024025026027028029030031032033034035036037038039040041042043044045046047048049050051052053054055056057058059060061062063064065066067068069070071072073074075076077078079080081082083084085086087088089090091092093094095096097098099100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
// (2022.9.18, 차재복, Cha Jae Bok, http://www.ktword.co.kr) // (DOM Tree 구성 요소) // ol : [ class = tree, type = (word,source,manual,db_table), lrType(left,right), moveType(copyWord,moveWord,moveNode) // , id = (subtree 산하 children의 fetch를 위한 id) ] // li : [ child = (자식 노드 수), id = (현재 id) ] // span : [ class = collapse ] // span : [ class = non-collapse ] // 아래 요소들이 경우에 따라 선택됨 // bullet : class = bullet (이벤트), class = nobullet // name : class = title // colon : class = colon // desc : class = desc // span 또는 button : edit 전용 // div : 해당 노드 상세 해설 보여주기용 // 자식 ol : 주로, 재귀 호출 fetchDataCreateOl(out) // 기능 : 서버로부터 데이터 가져오고, ol 생성 및 데이터 표출 후, 주어진 out에 ol을 자식으로 추가 // 호출 : [index.js] collapseSpanHandle() // [navi_base.js] collapseEvent() // [navi_search.js] asynctodo() function fetchDataCreateOl(out) { // ajax promise 호출 (서버로부터 데이터 가져오기) let typeParms = {'type' : out.dataset.type, 'lrType' : out.dataset.lrType, 'moveType' : out.dataset.moveType}; // (type:word,file,manual,db_table),(lrType:left,right),(moveType:copyWord,moveWord,moveNode) let choice = 'treeView'; let id = out.dataset.id; // spinner 이미지 보이기 // const spinner1 = document.getElementById('spinner1'); const spinner = out.closest('div').querySelector('.spinner'); if(spinner) fadeIn(spinner); // ajax promise 호출 let url = '/test/navigation/naviFetch.php?type='+typeParms.type+'&choice='+choice+'&id='+id; let method = 'get'; return ajaxPromise(url, method) // common_utils.js .then( response => { // (개발,디버깅중) // console.log(response.data); if(response.err_msg) alert(response.err_msg); let ol = ol_create(response.data, typeParms, id); // navi_base.js out.appendChild(ol); out.style.display = 'block'; // spinner 이미지 숨기기기 if(spinner) fadeOut(spinner); }, error => { alert(error); } ); } // 기능 : ol 요소 생성 // 호출 : [navi_base.js] fetchDataCreateOl() function ol_create(childrenData, typeParms, id) { // childrenData[i] = {id,name,child,desc,parent,item_type} // - word : {id,name,desc,item_type,child} // - manual : {id,name,desc,child} // typeParms = type 또는 {type:(word,source,manual,table),lrType:(left,right),moveType(copyWord,moveWord,moveNode)} //console.log(childrenData); // type 확인 설정 let type = (typeParms!='object' ? typeParms : typeParms.type); // ol 생성 let ol = document.createElement('ol'); ol.setAttribute('class','tree'); ol.style.padding = '5px 0px 5px 20px'; // ol 내 li들을 들여쓰기(20px) ol.dataset.id = id; // 현재 생성된 ol 하에 li 요소들 생성 for(let index in childrenData) { // 다중 선택 if(glob_var.user_type == '종합관리자') childrenData[index].mChoiceName = childrenData.mChoiceName; // li 생성 let li = li_create(childrenData[index], type); // navi_base.js // ol 요소에 매 li 마다 자식 노드로 붙임 ol.appendChild(li); } return ol; } // 기능 : li 요소 생성 // 호출 : [navi_base.js] ol_create() function li_create(liData, typeParms) { // liData : (parent, id, name, child, item_type, seq) // typeParms = type 또는 {type:(word,file,manual,table),lrType:(left,right),moveType(copyWord,moveWord,moveNode)} // 필드 구분 : bullet, name, colon, desc, moreShow, edit //console.log(liData); // type 확인 설정 let type = (typeof typeParms!='object' ? typeParms : typeParms.type); // li 생성 let li = document.createElement('li'); // li 중심으로, 각종 현재 상태 정보들을 저장 li.dataset.type = type; li.dataset.lrType = (typeParms.lrType ? typeParms.lrType : ''); li.dataset.moveType = (typeParms.moveType ? typeParms.moveType : ''); li.dataset.parent = liData.parent; li.dataset.child = liData.child; li.dataset.seq = liData.seq; li.dataset.section = '0'; // detail view 내 최초 section 번호 // (tree node=>id),(word node=>no) 구분 설정 if(liData.item_type == 'no') li.dataset.no = liData.id; else li.dataset.id = liData.id; li.style.listStyleType = 'none'; li.style.padding = '4px'; // collapse span 생성 let collapse = document.createElement('span'); li.appendChild(collapse); collapse.dataset.child = liData.child; if(liData.item_type == 'no') collapse.dataset.no = liData.id; else collapse.dataset.id = liData.id; collapse.setAttribute('class','collapse'); collapse.style.display = 'inline-block'; collapse.style.cursor = 'pointer'; // 현재 프로그램 상태 보여주기 if(glob_var.user_type == '종합관리자') collapse.title = (liData.item_type === 'no' ? 'no:' : 'id:') + liData.id + ', seq:' + liData.seq + ', child:' + liData.child + ', type:' + type + ', lrType:' + typeParms.lrType + ', moveType:' + typeParms.moveType + ', navi_base.js,navi_base_moreShow.js'; // collapse 이벤트 생성 if(type == 'word' && liData.item_type == 'no') collapse.addEventListener('click', detailSeparateView, false); // navi_base_moreShow.js else if(type == 'source' && liData.child == '0') collapse.addEventListener('click', (e) => { detailSourceView(collapse); // navi_base_moreShow.js }, false); else // ▷ (축소) ▽ (확장) collapse.addEventListener('click', collapseEvent); // navi_base.js // li 산하에, 각 항목들 생성하고, 선택적으로 collapse 수용 // bullet 생성 let bullet = document.createElement('a'); bullet.dataset.child = liData.child; bullet.href = '#'+liData.id; bullet.style.textDecoration = 'none'; if(liData.item_type == 'no') bullet.dataset.no = liData.id; else bullet.dataset.id = liData.id; bullet.setAttribute('class','bullet'); if(liData.child > 0) { bullet.style.color = 'red'; bullet.innerText = '▷'; } else { bullet.innerText = '▷'; } // name span 생성 let name = document.createElement('span'); name.dataset.child = liData.child; name.setAttribute('class','title'); name.style.marginLeft = '5px'; if(liData.item_type == 'no') { name.style.paddingBottom = '3px'; name.style.borderBottom = '1px dashed red'; } let text = document.createTextNode(liData.name); name.appendChild(text); let colon,desc; if(!typeParms.lrType) { // colon span 생성 colon = document.createElement('span'); colon.setAttribute('class','colon'); colon.style.margin = '0px 15px'; if(liData.desc) colon.innerHTML = ' : '; else colon.innerHTML = ' '; // desc span 생성 desc = document.createElement('span'); desc.setAttribute('class','desc'); if(liData.desc) desc.innerHTML = liData.desc; else desc.innerHTML = ''; } //alert(colon); // 조건에 따라 항목별 위치 설정 (자식 첨가) collapse.appendChild(bullet); collapse.appendChild(name); if(type == 'word' || type == 'source') { if(colon) collapse.appendChild(colon); if(desc) collapse.appendChild(desc); } else { if(colon) li.appendChild(colon); if(desc) li.appendChild(desc); } // edit (종합관리자용) if(glob_var.user_type == '종합관리자') { // type별로 각각 다른 편집 버튼 및 기능 구현 (type = word, source, manual, db_table) if(!typeParms.lrType) variousEditByType(li, liData, type); // navi_base_edit.js else { if(typeParms.lrType=='left') { let titleBtn = itemTitleEdit(li, liData, type); // navi_base_edit.js li.appendChild(titleBtn); let wordEditSpan = wordEdit(li, liData, type); // navi_edit_word.js li.appendChild(wordEditSpan); } multiChoiceMove(li, liData, typeParms); // navi_edit_multi.js } } // 말단 노드 상세 내역 (용어해설,소스코드 등) 보여주기 div if( !typeParms.lrType && (type == 'word' && liData.item_type == 'no') || (type == 'source' && liData.child == '0') ){ let div = document.createElement('div'); div.setAttribute('class','detail_view'); div.style.display = 'none'; div.style.marginTop = '10px'; div.dataset.id = liData.parent; div.dataset.no = liData.id; li.appendChild(div); } return li; } // 기능 : collapse 이벤트 처리기 (ver.2) // 호출 : [navi_base.js] li_create() function collapseEvent(e) { e.preventDefault(); if (this.dataset.child <= 0) return; // child ol 찾기 const childOl = this.parentNode.querySelector('ol.tree'); // bullet const bullet = this.querySelector('a'); if (bullet.innerText == '▷') { bullet.innerText = '▽'; // 자식 ol 이미 생성되었으면 단지 보이게 만 함 if (childOl) childOl.style.display = 'block'; // 자식 ol 생성 안되었으면 생성시킴 else { const li = this.closest('li'); fetchDataCreateOl(li); } } else if (bullet.innerText == '▽') { bullet.innerText = '▷'; childOl.style.display = 'none'; } }