빵 입니다.

배열을 사용한 함수형 프로그래밍, Todo 만들기 본문

프론트엔드/TODO 만들기

배열을 사용한 함수형 프로그래밍, Todo 만들기

bread-gee 2019. 2. 25. 15:38

기능 정의

  • Todo 입력
  • Todo 수정
  • Todo 삭제
  • Todo Total 갯수 체크
  • Todo 완료 갯수 체크
  • Todo 미완료 갯수 체크

시각적으로 보이는 리스트들을 todo들 관리를 쉽게하기 위해 배열에 넣었다.

배열을 관리하면 되기 때문에 상태 체크가 훨씬 쉽고 안정적이었다.

초기 실행함수를 만들어서 todo 추가하는 기능을 바인딩했다. (최초의 이벤트 바인딩)

부분적으로 스트링 템플릿을 사용해서 html에 있던 코드들을 많이 생략할 수 있었다.

ES6의 let, const, map, filter 등을 사용해서 코드를 더 간결하게 만들었다.

Todo 가 간단한 구조이기 때문에 변경될 때마다 화면을 새로 그리도록 만들었다.



HTML

        

Todo

    CSS

    @charset "UTF-8";
    @import url(//fonts.googleapis.com/earlyaccess/jejugothic.css);
    
    .todo_wrap{width:300px; margin:0 auto;}
    .todo_wrap h1{text-align:center;}
    .input_wrap{background:red;}
    .input_wrap:after{content:""; display:block; clear:both;}
    .input_wrap input{box-sizing:border-box; float:left; width:231px; height:40px; outline:0 none; border:1px solid #999; text-indent:5px;}
    .input_wrap input:focus{border-color:#03cf5d;}
    .input_wrap button{box-sizing:border-box; float:left; width:70px; height:40px; margin-left:-1px; outline:0 none; border:1px solid #03cf5d; background:#03cf5d; color:#fff;}
    .input_wrap button:hover{cursor:pointer;}
    
    .todo_list{list-style-type:none; margin:0; padding:30px 0;}
    .todo_list li{line-height:30px; font-family:'Noto Sans KR', sans-serif; font-size:13px;}
    .todo_list li input{vertical-align:middle;}
    .todo_list li label{vertical-align:middle; cursor:pointer;}
    .todo_list li button{box-sizing:border-box; width:20px; height:20px; outline:0 none; border:0 none; background:#ffffff; line-height:20px; color:red; vertical-align:middle; cursor:pointer; transition:background-color 0.5s ease;}
    .todo_list li button:hover{background:#03cf5d;}
    .todo_list .complete{text-decoration:line-through;}
    
    .todo_count{}
    .todo_count>span{position:relative; display:inline-block; width:30%; font-size:12px; text-align:center;}
    .todo_count>span>strong{position:relative; top:1px; display:inline-block; color:#1aaf5c;}
    

    JAVASCRIPT

    // 전역 객체
    let todoArray = [];
    
    // 최초 실행 함수
    function todoInit(){
        let btnAdd = document.getElementById('btnAdd');
        btnAdd.addEventListener("click", addNewItem);
        counting();
    }
    // TODO 추가
    function addNewItem(){
        let listWrap = document.querySelector('#todoList'),
            todoString = document.querySelector('#txtInput').value,
            id = new Date().getTime();
        let list = document.createElement("li");
        const addTmpl = `
                
                
                
        `;
        list.innerHTML = addTmpl;
        listWrap.appendChild(list);
        todoArray.push({id:id, item:todoString, chckState:false});
    
        list.querySelector('button').addEventListener("click", deleteItem);
        list.querySelector('input').addEventListener("change", completeItem);
    
        counting();
    }
    
    function deleteItem(e){
        let listWrap = document.querySelector('#todoList'),
            targetParent = event.currentTarget.parentNode,
            targetId = targetParent.querySelector('input').id;
    
        listWrap.removeChild(targetParent);
        todoArray = todoArray.filter(todo => todo.id != targetId);
        
        counting();
    }
    function completeItem(e){
        let targetId = e.currentTarget.id,
            parent = e.currentTarget.parentNode,
            curChckState = document.getElementById(targetId).checked;
        todoArray.map(todo => {
            if(todo.id == targetId){
                if(curChckState){
                    todo.chckState = true;
                    parent.className = 'complete';
                }else{
                    todo.chckState = false;
                    parent.className = '';
                }
            }
        });
        counting();
    }
    function counting(){
        let cntWrap = document.querySelector('#todoCount'),
            totalCnt = todoArray.length,
            comCnt = todoArray.filter(todo => todo.chckState).length,
            incomCnt = todoArray.filter(todo => !todo.chckState).length;
        const cntTmpl = `
            
                완료 ${comCnt}
            
                미완료 ${incomCnt}
            ${totalCnt}
        `;
        cntWrap.innerHTML = cntTmpl;
    }
    todoInit();
    


    CODEPEN 확인

    https://codepen.io/bread_gee/pen/ywVZRP

    반응형
    Comments