IT수업/JAVASCRIPT

IT 수업 9주차 (24) El_CRUD

워제하 2024. 2. 22. 11:58

 

 

Element를 CRUD 해볼 것이다.

 

우선 입력할 창을 만들어 입력한 값을 받아온다.



 

 

< 노드를 생성 >

이번에는 입력한 값을 출력하는 노드를 생성한다.

 

입력누르면 div태그가 늘어남

 

 

 

 

< 값 넣고 초기화하기 >

값을 넣으면 넣은 값들이 밑에 출력되면서 입력창은 초기화 된다.

'ㅁㅁㅁㅁ'을 제일 먼저 입력함

 

넣을 때 마다 class가 추가된다.

 

 

 

< 넣은 값이 처음으로 출력되게 함 >

apppend는 나중에 친 값이 맨 밑에 출력되지만 ( containerEl.appendChild(divEl); )

prepend는 나중에 친 값이 맨 위로 출력되도록 한다. ( containerEl.prependChild(divEl); )

'ㅇㅇㅇ' 을 제일 마지막에 입력함

 

 

 

< 삭제 >

휴지통을 클릭하면 삭제되는 것을 해볼 것이다.

 

구글아이콘에 들어가 delete 아이콘을 가져왔다.

 

그리고 가져온 google icon 을 등록한다.

 

값을 입력한 뒤 휴지통을 누르게 되면 해당 값이 삭제 되는 것을 볼 수 있다.

선택한 삭제 값이 나오는 것을 볼 수 있다.

 

 

 

 

 

< 엔터 적용 >

 

입력버튼을 누르지 않고 엔터를 눌러도 값이 들어가는 것을 적용해본다. ( 'keydown' )

엔터는 아스키코드로 13번이므로 event.keyCode==13 을 해주면 된다.

이렇게 위에 코드를 복사 붙여넣기 해도 되지만 코드중복이므로 함수를 사용할 것이다

 

 

 

 

 

< 함수 사용해서 연결시킴 >

createNode()를 만들어서 위에 중복 코드를 삭제한 뒤 입력시켜 준다.

 

 

 

 

 

 

< 유효성검사 >

내용을 입력하면 들어가고

내용을 입력하지 않고 입력하면 뜨지 않는다.

 

if else 를 사용한다.

 

< 내용 입력했을 때 >

 

 

< 내용 입력하지 않았을 때 >

 

 

 

 

 

< 드래그 이벤트 >

 

이번에는 드래그 이벤트를 추가해 볼 것이다.

먼저 드랍하기 전의 좌표를 저장한다.

 

그리고 function createNode()안에 드래그 이벤트를 입력한다.

 

이렇게 a, b, c, d 순서로 입력하여 출력된 것이 드래그를 하여 순서를 바꿀 수 있다.

 

콘솔창에는 이렇게 dragstart event 와 drop event 가 나타나게 된다.

 

 

 

< 전체 코드 >

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
   
    <!-- GOOGLE ICON -->
    <style>
        .material-symbols-outlined {
          font-variation-settings:
          'FILL' 0,
          'wght' 400,
          'GRAD' 0,
          'opsz' 24;
          font-size:1rem;
        }

        .draggable--style{
            background-color:gray;
            opacity: .5;
        }
        .drop--style{
            background-color:white;
            opacity: 1;
        }
    </style>

</head>
<body>
    <input type="text" class="inputEl"><span> | </span><button class="btn">입력</button>
    <hr>
    <div class="container">

    </div>
    <script>
        const inputEl = document.querySelector(".inputEl");
        const btnEl = document.querySelector(".btn");
        const containerEl = document.querySelector('.container');

        btnEl.addEventListener('click',function(){  
            createNode()
        })
        inputEl.addEventListener('keydown',function(event){
            console.log(event.keyCode);
            if(event.keyCode==13){
                createNode()
            }
        })
        function isValid(value){
            //console.log(typeof value);
            if(value==="")
                return false;
           
            return true;
        }

        let beforeEl = null; //드랍 이전 El 저장
        let beforeYpos = null;  //드랍 이전 El의 Y좌표 저장
        function createNode(){
                const contents = inputEl.value; //input value 가져오기
                const result = isValid(contents);
                if(result){
                    console.log("clicked..value : ",contents);  
                    const divEl =  document.createElement('div')    //div태그 생성
                    divEl.setAttribute('style','width:300px;height : 40px;border:1px solid;padding:2px;margin:2px;')                    
                    //----------------------
                    //드래그이벤트 추가
                    //----------------------
                    divEl.setAttribute('draggable',true);   //drag가능상태로 요소 설정
                    divEl.addEventListener('dragstart',function(event){
                        console.log('dragstart event',event);
                        console.log('dragstart target',event.target);    
                        beforeYpos= event.pageY;
                        beforeEl = event.target;
                       

                    })
                    divEl.addEventListener('dragover',function(event){
                        event.preventDefault();
                        //console.log(event);    
                    })
                    divEl.addEventListener('drop',function(event){
                        event.preventDefault();
                        console.log('drop event',event);
                        console.log('drop target',event.target)  
                       
                        if(beforeYpos<event.pageY) //위에서 아래로 이동
                        {
                            beforeEl.before(event.target);
                        }
                        else    //아래서 위로 이동
                        {
                            beforeEl.after(event.target);
                        }    
                    })

                    //----------------------

                    divEl.innerHTML=contents;   //input value 를 div의 content에 넣기
                    const delEl = document.createElement('span');
                   
                    delEl.classList.add('material-symbols-outlined');    //google icon class 등록
                    delEl.innerHTML='delete';   //google icon name 지정
                    delEl.setAttribute('style','cursor:pointer');
                    delEl.addEventListener('click',function(){
                        console.log('clicked..');
                        //부모노드 찾기
                        const parentEl =  delEl.parentNode;
                        console.log(parentEl);
                        //부모노드 삭제
                        parentEl.remove();

                    })
                   
                    divEl.appendChild(delEl);   //divEl의 자식으로 연결

                    //containerEl.appendChild(divEl); //container의 자식으로 연결(마지막)
                    containerEl.prepend(divEl); //container의 자식으로 연결(첫노드로연결)
                    inputEl.value="";   //input value 초기화
                }
                else{
                    alert("내용을 입력하세요..");
                    inputEl.value="";
                }


        }
    </script>
</body>
</html>

 

 

 

 

 

< CRUD 연습하기 >

// form의 기본기능은 비활성화합니다 (  답 : initial-scale=1.0 )

// 입력버튼을 눌렀을때 table의 tbody에 입력된 (이름/나이/주소/삭제버튼)이 생성될수 있도록합니다
// 입력된 노드의 이름/나이/주소를 수정할수 있도록합니다.
// 특정행의 삭제버튼을 클릭했을때 해당 행이 삭제 될수 있도록 합니다.
// 특정행의 위치를 위로이동/아래로 이동이 가능하도록 합니다(나중에)

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
   
    <!-- GOOGLE ICON -->
    <style>
        *{
            font-size: 1rem;
        }
        .material-symbols-outlined {
          font-variation-settings:
          'FILL' 0,
          'wght' 300,
          'GRAD' 0,
          'opsz' 24;
          font-size:1.5rem;
        }
        input{
            height : 35px;
        }
        .btn{
            width : 75px;
            height : 35px;
            border-radius: 5px;
            background-color: white;
            cursor: pointer;
        }

        th,td{
            width:50px;
            height : 35px;
            border : 1px solid;
            margin : 2px;
        }

        th:nth-child(3),
        td:nth-child(3)
        {
            width : 700px;
        }
        .container{
            border: 1px solid;
            display: flex;
        }

    </style>

</head>
<body>
    <form action="" name="joinForm" onsubmit="return false">
        <input name="username" placeholder="이름을 입력하세요" >
        <input name="age"  placeholder="나이를 입력하세요">
        <input name="address" placeholder="주소를 입력하세요">
        <button class="btn">입력</button>
    </form>
    <hr>
    <table>
        <thead>
            <tr>
                <th>이름</th>
                <th>나이</th>
                <th>주소</th>
                <th>삭제</th>
            </tr>  
        </thead>
        <tbody>
            <div class="container">
                <div class="d1"></div>
                <div class="d2"></div>
                <div class="d3"></div>
                <div class="d4"></div>
            </div>
           
        </tbody>
       
    </table>

    </div>
    <script>
        // form의 기본기능은 비활성화합니다
        //입력버튼을 눌렀을때 table의 tbody에 입력된 (이름/나이/주소/삭제버튼)이 생성될수 있도록합니다
        //입력된 노드의 이름/나이/주소를 수정할수 있도록합니다.
        //특정행의 삭제버튼을 클릭했을때 해당 행이 삭제 될수 있도록 합니다.
       
        //특정행의 위치를 위로이동/아래로 이동이 가능하도록 합니다(나중에)



        const btnEl = document.querySelector('.btn');
        const formEl = document.joinForm;
        const usernameEl = formEl.username;
        const ageEl = formEl.age;
        const addressEl = formEl.address;

        const tableBodyEl = document.querySelector('table tbody');

        btnEl.addEventListener('click', function(){
            if(isValid()){
                createNode();
            }
            else{
                alert("다시 입력하세요..");
            }

            //초기화 시키는 작업
            usernameEl.value='';
            ageEl.value='';
            addressEl.value='';
        })

        function isValid(){
            return !(isNaN(ageEl.value)); // 숫자가 아니면 true / 숫자면 false
           
        }

        function createNode(){

           
            const tr = document.createElement('tr'); //tr생성
            const td1 = document.createElement('td'); //td생성
            td1.innerHTML = usernameEl.value;
            const td2 = document.createElement('td');
            td2.innerHTML = ageEl.value;
            const td3 = document.createElement('td');
            td3.innerHTML = addressEl.value;
            const td4 = document.createElement('td');
            const delEl = document.createElement('span');
            delEl.classList.add('material-symbols-outlined');
            delEl.innerHTML='delete';

            delEl.setAttribute('style', 'cursor:pointer');
            delEl.addEventListener('click', function(){
                const parentEl = delEl.parentNode.parentNode;
                console.log(parentEl);
                parentEl.remove();
            })

            td4.appendChild(delEl);


            //tr -> td연결
            tr.appendChild(td1);
            tr.appendChild(td2);
            tr.appendChild(td3);
            tr.appendChild(td4);

            //tbody - td 연결
            tableBodyEl.appendChild(tr)
        }

         

    </script>
</body>
</html>

 

 

 

< 결과 >

값 넣었을 때

 

 

나이에 숫자 입력하지 않았을 때

 

 

행 삭제 시

 

 

 

여기서  박스 선택시 입력한 이름을 변경할 수 있는 코드를 추가해본다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
   
    <!-- GOOGLE ICON -->
    <style>
        *{
            font-size: 1rem;
        }
        .material-symbols-outlined {
          font-variation-settings:
          'FILL' 0,
          'wght' 300,
          'GRAD' 0,
          'opsz' 24;
          font-size:1.5rem;
        }
        input{
            height : 35px;
        }
        .btn{
            width : 75px;
            height : 35px;
            border-radius: 5px;
            background-color: white;
            cursor: pointer;
        }

        th,td{
            width:50px;
            height : 35px;
            border : 1px solid;
            margin : 2px;
        }

        th:nth-child(3),
        td:nth-child(3)
        {
            width : 700px;
        }
        .container{
            border: 1px solid;
            display: flex;
        }

    </style>

</head>
<body>
    <form action="" name="joinForm" onsubmit="return false">
        <input name="username" placeholder="이름을 입력하세요" >
        <input name="age"  placeholder="나이를 입력하세요">
        <input name="address" placeholder="주소를 입력하세요">
        <button class="btn">입력</button>
    </form>
    <hr>
    <table>
        <thead>
            <tr>
                <th>이름</th>
                <th>나이</th>
                <th>주소</th>
                <th>삭제</th>
            </tr>  
        </thead>
        <tbody>
            <div class="container">
                <div class="d1"></div>
                <div class="d2"></div>
                <div class="d3"></div>
                <div class="d4"></div>
            </div>
           
        </tbody>
       
    </table>

    </div>
    <script>
        // form의 기본기능은 비활성화합니다
        //입력버튼을 눌렀을때 table의 tbody에 입력된 (이름/나이/주소/삭제버튼)이 생성될수 있도록합니다
        //입력된 노드의 이름/나이/주소를 수정할수 있도록합니다.
        //특정행의 삭제버튼을 클릭했을때 해당 행이 삭제 될수 있도록 합니다.
       
        //특정행의 위치를 위로이동/아래로 이동이 가능하도록 합니다(나중에)



        const btnEl = document.querySelector('.btn');
        const formEl = document.joinForm;
        const usernameEl = formEl.username;
        const ageEl = formEl.age;
        const addressEl = formEl.address;

        const tableBodyEl = document.querySelector('table tbody');

        btnEl.addEventListener('click', function(){
            if(isValid()){
                createNode();
            }
            else{
                alert("다시 입력하세요..");
            }

            //초기화 시키는 작업
            usernameEl.value='';
            ageEl.value='';
            addressEl.value='';
        })

        function isValid(){
            return !(isNaN(ageEl.value)); // 숫자가 아니면 true / 숫자면 false
           
        }

        let td01_id_val=0; // 전역변수
        function createNode(){
            td01_id_val++;

           
            const tr = document.createElement('tr'); //tr생성
            tr.setAttribute('draggable',true); //드래그 가능하도록
            const td1 = document.createElement('td'); //td생성

            //--------------------
            // 라벨 체크 시 이름 변경 가능하도록
            // --------------------
           
            const chk1 = document.createElement('input');
            chk1.setAttribute('type','checkbox');
            chk1.setAttribute('id',`name_id_01_${td01_id_val}`);
            chk1.style.display="none"; //체크박스 숨기기

            const chk1_label = document.createElement('label');
            chk1_label.setAttribute('for',`name_id_01_${td01_id_val}`);
            chk1_label.setAttribute('style','display:block; position:relative;')
           
           
            const input1 = document.createElement('input');
            input1.value = usernameEl.value;
            input1.setAttribute('disabled',true);
            input1.setAttribute('style','position:relative; z-index:-1;');

            chk1.addEventListener('change',function(){
                const inputEl = chk1.nextSibling.firstChild;
                if(event.target.checked){
                    inputEl.style.zIndex=1; //수정 가능하도록 index를 올려줌
                    inputEl.disabled=false;
                   
                }
                else{
                    inputEl.disabled=true;
                }
            });

            input1.addEventListener('keydown',function(event){
                if(event.keyCode==13){
                    input1.setAttribute('style','position:relative; z-index:-1;');
                    input1.setAttribute('disabled',true);
                    const chkEl = input1.parentNode.previousSibling;
                    chkEl.checked=false;
                } // enter 치면 원래대로 돌림
            })

            td1.append(input1);
            input1.addEventListener('dblclick',function(){
                // input1.setAttribute('disabled',false);
            })
           
           
           
           
            chk1_label.appendChild(input1);
            td1.append(chk1);
            td1.append(chk1_label);
           
            // ------------------------
           
           
            const td2 = document.createElement('td');
            td2.innerHTML = ageEl.value;
            const td3 = document.createElement('td');
            td3.innerHTML = addressEl.value;
            const td4 = document.createElement('td');
            const delEl = document.createElement('span');
            delEl.classList.add('material-symbols-outlined');
            delEl.innerHTML='delete';

            delEl.setAttribute('style', 'cursor:pointer');
            delEl.addEventListener('click', function(){
                const parentEl = delEl.parentNode.parentNode;
                console.log(parentEl);
                parentEl.remove();
            })

            td4.appendChild(delEl);


            //tr -> td연결
            tr.appendChild(td1);
            tr.appendChild(td2);
            tr.appendChild(td3);
            tr.appendChild(td4);

            //tbody - td 연결
            tableBodyEl.appendChild(tr)
        }

         

    </script>
</body>
</html>

 

더블 클릭하면 이름을 변경할 수 있고 enter를 치면 변경한 값이 들어가게 된다.

 

 

 

 

 

 

참고 : https://fonts.google.com/icons?selected=Material+Symbols+Outlined:delete:FILL@0;wght@400;GRAD@0;opsz@24&icon.query=trash