본문 바로가기
반응형

완성이미지

 

 

JavaScript 로 메뉴 카테고리 구현하기

 

기능 설명

1. 메뉴 추가를 누르면 input text  창이 나오고, 해당 내용 입력 후 저장을 누르면 하위카테고리가 생김

2. 가장상위(depth) 는 전체보기를 클릭후 메뉴추가

3. 삭제하고자 하는 메뉴를 클릭 후 삭제버튼을 누르면 삭제됨.

4. 다만 하위항목이 존재할경우 삭제가 되지 않음

5. 별도의 DB가 없이 LocalStorage 를 이용하여 저장할 예정

 

 

 


 

1. script 를 제외한 head~body 부분

<!DOCTYPE html>
<html lang="ko">
<head>
    <title>메뉴</title>
    <style>
        .highlight {
            background-color: yellow;
        }
        #itemList > li {
            list-style-type: none;
        }
    </style>
</head>
<body>
    
    
    <h1>메뉴 관리</h1>
    <button id="add">메뉴 추가</button>
    <form id="itemForm">
    <ul id="itemList">
        <li class="highlight" id="0"><h1>전체보기</h1></li>
    </ul>
   
    <button id="submit">메뉴 저장</button>
    </form><br>
    <button id="delete">삭제</button>

 

itemList 에 이제 script 를 이용하여 동적으로 메뉴를 생성

 

Script 부분

1. list 항목 추가 후 appendChild 를 통하여 동적으로 메뉴 리스트 추가

        var mylist = [];
        
        mylist.push({"id" : "1", "parent":null, "text": "1번데이터"});
        mylist.push({"id" : "2", "parent":null, "text": "2번데이터"});
        mylist.push({"id" : "3", "parent":"1", "text": "3번데이터"});
        mylist.push({"id" : "4", "parent":"3", "text": "4번데이터"});
        mylist.push({"id" : "5", "parent":null, "text": "5번데이터"});
        mylist.push({"id" : "6", "parent":"2", "text": "6번데이터"});
        mylist.push({"id" : "7", "parent":null, "text": "7번데이터"});

/*
mylist 는 id 값과 parent (하위항목일경우 parent의 id 찾기 위한 값), 내용이 들어갈 text (사실상 value) 로 만들었음
*/

		//초기 로드일 경우 mylist 를 이용하여 화면에뿌림, 수정을 거쳤을 경우 해당 내용으로.
        if(!localStorage.getItem('myItemList')){
            localStorage.setItem('myItemList', JSON.stringify(mylist));  
        }
        mylist =  JSON.parse(localStorage.getItem('myItemList'));

        let length = mylist.length;
        let count = length;

		//forEach 를 이용하여 각 list 를 그리는데, pid(parent) 가 있을 경우 해당 하위항목으로 위치시킴
        mylist.forEach(element => {
            let li = document.createElement('li');
            li.id = element.id;
            li.textContent = element.text;
            let ul = document.createElement('ul');
            ul.id = element.id;
            
            if(element.parent != null){
            
                document.getElementById(element.parent).appendChild(ul);
                ul.appendChild(li);
                // itemList.appendChild(ul);
            }else{
                document.getElementById("itemList").appendChild(ul);
                ul.appendChild(li);
                //itemList.appendChild(li);
            }
        });

 

 

2. 선택시 하이라이트 효과 및 선택한 메뉴에 event 를 적용하기 위한 class 동적 추가 (삭제나 하위항목 추가에 사용)

        //itemList 에 EventListener 추가
        document.querySelectorAll('#itemList li').forEach(li => {
            li.addEventListener('click', (event)=>{
                // 하위요소가 없으면 highlightElement 실행
                if (!li.querySelector('ul')) {
                    highlightElement(li);
                }
                // 부모요소까지 이벤트 미치지 못하도록
                event.stopPropagation();
            })
        })

//highlight 라는 class 를 추가(style css 보면 highlight 설정해둔 것을 알 수 있음)
        const highlightElement = element => {
            document.querySelectorAll('#itemList li').forEach(li =>{
                li.classList.remove('highlight');
            });
            element.classList.add('highlight');
        }

 

 

3. 항목 선택 후 메뉴 추가 이벤트

        document.getElementById('add').addEventListener('click', function() {
            var highlightedElement = document.querySelectorAll('.highlight')[0];
            let ul = document.createElement('ul');
            ul.id=highlightElement.id;
            let li = document.createElement('li');

            let pid = highlightedElement.id==0 ? null : highlightedElement.id
            count++;

            li.innerHTML = `<input type='text' class='addMenu' id=`+count+` name=`+pid+` required></input>`;
            ul.appendChild(li);
            
            highlightedElement.insertAdjacentElement('afterend', ul);
        });
        
        //innerHTML 에 input 을 넣었고, appendChild 를 통하여 선택한 하위메뉴에 들어가도록 함.

 

4. 메뉴 추가 후 저장버튼으로 메뉴 수정


        document.getElementById('itemForm').addEventListener('submit', function(event) {
            event.preventDefault(); // 기본 제출 동작 방지
            
            let inputValues = [];
            let inputs = document.querySelectorAll('input[type="text"]');

            inputs.forEach(function(input) {
                let inputId = input.id;
                let inputName = input.name == "null" ? null : input.name;
                console.log(inputName);
                let inputText = input.value;
                mylist.push({"id" : inputId, "parent":inputName, "text": inputText})
            });

            console.log("after" + mylist);

//LocalStorage 에 저장한 list (myItemList) 업데이트
            localStorage.setItem('myItemList', JSON.stringify(mylist));  
            location.reload();

        });

 

5. 삭제버튼 클릭시 이벤트 

 //삭제 버튼 클릭시 이벤트 실행. mylist 에서 해당항목 splice 를 통해 삭제 후 리로드로 화면을 다시 그림
 		document.getElementById('delete').addEventListener('click', function() {
            event.preventDefault(); // 기본 제출 동작 방지
            
            var highlightedElement = document.querySelectorAll('.highlight')[0];
            let id = highlightedElement.id;

            if(checkParent(id)){
                alert("하위항목이 남아있습니다.")
            }else{
                for (let i = mylist.length -1 ; i>=0 ; i--){
                    if(mylist[i].id === id){
                        mylist.splice(i, 1);
                    }
                 }
            }


            localStorage.setItem('myItemList', JSON.stringify(mylist));  
            location.reload();
        });

//하위 항목이 존재하는지 확인
        function checkParent(id){
            for(let i = mylist.length - 1 ; i >= 0 ; i--){
                if(mylist[i].parent==id){
                    return true;
                }
            }
            return false;
        }

 

menu1.html
0.01MB

 

 

전체코드는 html 참고

728x90
반응형

한걸음 한걸음

개인적인 기록