001002003004005006007008009010011012013014015016017018019020021022023024025026027028029030031032033034035036037038039040041042043044045046047048049050051052053054055056057058059060061062063064065066067068069070071072073074075076077078079080081082083084085086087088089090091092093094095096097098099100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
// (2020.11.25, 차재복, Cha Jae Bok, http://www.ktword.co.kr) // (편집자용) 편집용 버튼 생성 유지 function move_btn (data) { // 버튼 요소 생성 및 스타일 설정 let btn = document.createElement('button'); btn.id = 'move_btn_'+data.id; btn.setAttribute('style','margin-left:20px; padding:0px; font-size:9px; font-style:italic'); // (편집자용) 호출 내역 보여주기 btn.title = 'reform_edit_move.js \n'+'move_btn() \n'+'reform.'+data.id; // 버튼 요소 내 텍스트 'Move ∨' 요소 설정 const move_text = document.createTextNode('Move ∨'); btn.appendChild(move_text); // 버튼 요소에 이벤트리스너 설정 btn.addEventListener('click', function(e) { const div_name = 'move_div_'; // 'move_div_(id)' 명칭을 갖는 요소 검색/선택 let div_id = document.getElementById(div_name+data.id); if (div_id) { // 하부 div의 show/hide itemShowHide(div_id, btn); // common_utils.js } else { // 편집용 div 생성 let div = move_div(data, div_name); // reform_edit_move.js insertAfter(e.target, div); // common_utils.js // 클릭 요소 (∨,∧) 바꿈 btn.innerHTML = btn.innerText.replace('∨','∧'); } }); return btn; } // (편집자용) id move div function move_div (data) { // container div 요소 생성 let div = document.createElement('div'); // div 요소의 스타일 설정 div.style.padding = '0'; // div 요소에 정보 저장 div.id = 'move_div_'+data.id; div.dataset.id = data.id; div.dataset.parent = data.parent; div.dataset.sub_seq = data.sub_seq; div.dataset.path2node = data.path2node; // id 위로 이동 버튼 let id_up = document.createElement('button'); id_up.ch = 'id_up'; let id_up_text = document.createTextNode('위로'); id_up.appendChild(id_up_text); id_up.addEventListener('click', id_move_gen_ajax); // 이벤트리스너 등록 추가 (id_move_gen_ajax 실행) div.appendChild(id_up); // id 아래로 이동 버튼 let id_down = document.createElement('button'); id_down.ch = 'id_down'; let id_down_text = document.createTextNode('아래로'); id_down.appendChild(id_down_text); id_down.addEventListener('click', id_move_gen_ajax); // 이벤트리스너 등록 추가 (id_move_gen_ajax 실행) div.appendChild(id_down); // id 맨 처음으로 이동 버튼 let id_first = document.createElement('button'); id_first.ch = 'id_first'; let id_first_text = document.createTextNode('처음'); id_first.appendChild(id_first_text); id_first.addEventListener('click', id_move_gen_ajax); // 이벤트리스너 등록 추가 (id_move_gen_ajax 실행) div.appendChild(id_first); // id 맨 마지막으로 이동 버튼 let id_last = document.createElement('button'); id_last.ch = 'id_last'; let id_last_text = document.createTextNode('끝'); id_last.appendChild(id_last_text); id_last.addEventListener('click', id_move_gen_ajax); // 이벤트리스너 등록 추가 (id_move_gen_ajax 실행) div.appendChild(id_last); // id 레벨업 버튼 let id_level_up = document.createElement('button'); id_level_up.ch = 'id_level_up'; let id_level_up_text = document.createTextNode('레벨업'); id_level_up.appendChild(id_level_up_text); id_level_up.addEventListener('click', id_move_gen_ajax); // 이벤트리스너 등록 추가 (id_move_gen_ajax 실행) div.appendChild(id_level_up); // id 레벨다운 버튼 let id_level_down = document.createElement('button'); id_level_down.ch = 'id_level_down'; let id_level_down_text = document.createTextNode('레벨다운'); id_level_down.appendChild(id_level_down_text); id_level_down.addEventListener('click', id_move_gen_ajax); // 이벤트리스너 등록 추가 (id_move_gen_ajax 실행) div.appendChild(id_level_down); // 결과 div 리턴 return div; } // (편집자용) id move update function id_move_gen_ajax() { // 전달변수 설정 let ch = this.ch; // choice 종류 let id = this.closest('div').dataset.id; // 현재 노드의 id let parent = this.closest('div').dataset.parent; // 현재 노드의 부모 노드 id let sub_seq = this.closest('div').dataset.sub_seq // 현재 노드의 sub_seq let path2node = this.closest('div').dataset.path2node; // 현재 노드의 path2node let carrier_id, text; carrier_id = this.carrier_id; // 값을 갖는 carrier id if (carrier_id) text = document.getElementById(carrier_id).value; // text : 생성용 텍스트 // (디버깅용) if (ch=='id_delete') { if(!confirm('삭제 여부')) return; } // (디버깅용) // if (!confirm('parent='+parent+', id='+id+', ch='+ch+', text='+text)) return; let xhr = new XMLHttpRequest(); let method = 'POST'; let url = '../reform/reform_update.php'; xhr.open(method, url); xhr.onreadystatechange = function() { if (xhr.readyState === 4 && xhr.status === 200) { /* // (디버깅용) if(xhr.responseText=='' || xhr.responseText=='null') { alert('빈문자열 만 또는 null 문자 만 옴'); console.log(xhr.responseText); return; } */ // JSON.parse 및 예외처리 let data; try { data = JSON.parse(xhr.responseText); } catch (e) { console.log(xhr.responseText); alert('서버에서 반환된 데이터 내 에러 추정...console.log 확인 필요'); return; } // (디버깅용) if (data.err_msg) { alert('서버 db 처리 중 에러 발생\n'+data.err_msg); return; } // 주요 노드별 위치 let parentOl = document.getElementById('olid_'+parent); let parentLi = parentOl.parentNode; let currentLi = document.getElementById('lid_'+id); // 현재 노드의 부모의 sesseionStorage let currentParentObject = JSON.parse(sessionStorage.getItem('sid_' + parent)); // 이동 전에 현재 노드 DOM 요소 미리 제거 if (ch=='id_up' || ch=='id_down' || ch=='id_first' || ch=='id_last' || ch=='id_level_up' || ch=='id_level_down') parentOl.removeChild(currentLi); // 위로,아래로 이동 if (ch=='id_up' || ch=='id_down') { // 디버깅용 // console.log(data); // 현재 parent 노드 산하 ol을 대체할 신규 ol 생성 let createdOl = ol_create(parent, data.nextParentChilds, parentLi); // (id, data, out) // 현재 parent 노드 산하의 old ol을 created ol로 교체 parentOl.replaceWith(createdOl); // 교체된 ol 산하 li 모두에 이벤트 설정 event4li (createdOl); // 서버로부터 받은 nextParentChilds를 현재 parent 산하 자식정보로써 sessionStorage에 저장 let targetParentSession = JSON.stringify(data.nextParentChilds); sessionStorage.setItem('sid_' + parent, targetParentSession); // 맨처음으로 이동 } else if (ch=='id_first') { // 현재 parent 노드의 최초 노드 다음에 생성된 li 노드를 삽입 let li = li_create(id, data.nextParentChilds[1]); parentOl.insertBefore(li, parentOl.firstChild) // 삽입된 li에 이벤트 설정 event4Singleli (li); // 서버로부터 받은 nextParentChilds를 현재 parent 산하 자식정보로써 sessionStorage에 저장 let targetParentSession = JSON.stringify(data.nextParentChilds); sessionStorage.setItem('sid_' + parent, targetParentSession); // 맨끝으로 이동 } else if (ch=='id_last') { // 레벨업,레벨다운 이동 } else if (ch=='id_level_up' || ch=='id_level_down') { // 변수 설정 let nextParentId = data.next_parent; let nextSub_seq = data.sub_seq; // 현재 노드의 parent의 sessionStorage로부터 해당 id 만 제거 후 다시 저장 for (let index in currentParentObject ) { if(currentParentObject[index].id==id) { delete currentParentObject[index]; } } let deletedStorage = JSON.stringify(currentParentObject); sessionStorage.setItem('sid_' + parent, deletedStorage); // 서버로부터 받은 nextParentChilds를 nextParentId로써 sessionStorage에 저장 let targetParentSession = JSON.stringify(data.nextParentChilds); sessionStorage.setItem('sid_' + nextParentId, targetParentSession); // 레벨업 처리 if (ch=='id_level_up') { // 현재 노드의 상위 레벨에서, 현재 노드의 parent 노드 다음에 현재 노드를 삽입 let li_after = document.getElementById('lid_'+parent); let li = li_create(id, data.nextParentChilds[nextSub_seq]); insertAfter(li_after, li); // 직후 삽입된 li에 이벤트 설정 event4Singleli (li); // 기존 있던 자리에서, 자식이 하나도 없는 경우 if (!parentOl.hasChildNodes()) { // 기존 부모 ol 삭제 parentLi.removeChild(parentOl) // 현재 직전 li의 a 부여 취소 if(parentLi.firstChild.nodeName == 'A') { let a = navi_create(parent, '0'); // parent:parent id, '0':자식없음 -> ex_run/navi_testing.js parentLi.replaceChild(a, parentLi.firstChild); } } // 레벨다운 처리 } else if (ch=='id_level_down') { // 현재 노드 직전 노드의 하위 레벨의 li 및 ol 찾음 let targetLi = document.getElementById('lid_'+nextParentId); let oldOl = document.getElementById('olid_'+nextParentId); // 해당 li 하부에 기존 ol 노드가 있다면 삭제 if(oldOl) targetLi.removeChild( oldOl ); // 해당 li 하부에 ol 생성 let targetParentObject = data.nextParentChilds; let createdOl = ol_create(nextParentId, targetParentObject, targetLi); targetLi.appendChild(createdOl); // createdOl의 산하 li들에 이벤트 설정 event4li (createdOl); // 해당 li의 a 부여 여부 if(targetLi.firstChild.nodeName != 'A') { let a = navi_create(parent, nextParentId, Object.keys(data.nextParentChilds).length); targetLi.replaceChild(a, targetLi.firstChild); a.innerText = '▽'; event4Singleli (targetLi); } } // 현재 노드 삭제 } else if (ch == 'id_delete') { // 현재 노드 제거 parentOl.removeChild(currentLi); if (data.ok == true) alert('삭제 성공 ; 형제수='+data.sibling); // 현재 부모 내 자식이 하나도 없는 경우 if (!parentOl.hasChildNodes()) { // 현재 부모 sessionStorage의 sub_seq,child 수정 currentParentObject[sub_seq].child = '0'; // '0':자식없음 let currentParentSession = JSON.stringify(currentParentObject); sessionStorage.setItem('sid_' + parent, currentParentSession); // 부모 ol 삭제 parentLi.removeChild(parentOl) // 부모 li의 a 부여 취소 if(parentLi.firstChild.nodeName == 'A') { let a = navi_create(parent, '0'); // parent:parent id, '0':자식없음 -> ex_run/navi_testing.js parentLi.replaceChild(a, parentLi.firstChild); } } // 자식 노드 생성 } else if (ch == 'id_child') { // 현재 li의 a 부여 if(currentLi.firstChild.nodeName != 'A') { let a = navi_create(id, '1'); // id:parent id, '1':자식없음 -> ex_run/navi_testing.js currentLi.replaceChild(a, currentLi.firstChild); a.innerText = '▽'; event4Singleli(currentLi); // -> ex_run/navi_testing.js } // 서버로부터 받은 nextParentChilds로부터 현재 노드의 신규 자식 노드 생성 let ol_created = ol_create(id, data.nextParentChilds, currentLi); // (id, data, out) currentLi.appendChild(ol_created); // 현재 부모 sessionStorage에서 현재 노드의 child 필드 수정 currentParentObject[sub_seq].child = '1'; let currentParentSession = JSON.stringify(currentParentObject); sessionStorage.setItem('sid_' + parent, currentParentSession); // 서버로부터 받은 nextParentChilds를 현재 노드 산하 자식정보로써 sessionStorage에 저장 let currentTargetSession = JSON.stringify(data.nextParentChilds); sessionStorage.setItem('sid_' + id, currentTargetSession); // gen_del_div 사라짐 const gen_del_div = document.getElementById('gen_del_div_'+id); itemShowHide(gen_del_div, this); // -> base_utils/common_utils.js // 이전,이후 노드 생성 } else if (ch == 'id_prepend' || ch == 'id_append') { // ch == 'id_prepend' // 서버로부터 받은 nextParentChilds로부터 현재 노드의 이전 및 이후 노드 생성 let li = li_create(parent, data.nextParentChilds[data.sub_seq]); // (par_id, data) if (ch == 'id_prepend') { parentOl.insertBefore(li, currentLi); // (newNode, referenceNode) } else if (ch == 'id_append') { insertAfter(currentLi, li); // (referenceNode, newNode) } // 서버로부터 받은 nextParentChilds를 현재 parent의 산하 자식정보로써 sessionStorage에 저장 let currentParentSession = JSON.stringify(data.nextParentChilds); sessionStorage.setItem('sid_' + parent, currentParentSession); // gen_del_div 사라짐 const gen_del_div = document.getElementById('gen_del_div_'+id); itemShowHide(gen_del_div, this); // -> base_utils/common_utils.js } } }; xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded'); xhr.send('id='+id+'&ch='+ch+'&text='+encodeURIComponent(text)); }