TodoList-todolist

hyuko·2023년 4월 3일
0

main의 또 다른 한 부분인 todo

이전에 작업을 하면서 main-container 에 이미 우리는 userInfo라는
페이지가 있습니다. 아직 우리는 페이지에 관해서 주소에 관한 개념이 없다고
가정하에 페이지를 완성하고 있습니다.

그렇기 때문에 같은 container 로 작업을 하되 hidden css를 따로 주어
javascript에서 제어를 해보도록 하겠습니다.

첫번째 input에 todo 를 적으면 todo가 작성한 시간으로 하나씩 생성
두번째 생성된 투두는 update 버튼과 delete버튼을 두어 각각 가능해야함

일단 눈에 보이는 기능은 두가지입니다.
index.html 부터 가보도록 하겠습니다.


index.html


<main class="main-container main-hidden">
            <header class="main-header">
                <h1 class="main-title">ToDo</h1>
                <div class="todo-input-container">
                    <i class="fa-regular fa-file-lines"></i>
                    <input type="text" class="todo-input" placeholder="Please Enter To Do...">
                    <button class="add-todo-button"><i class="fa-solid fa-plus"></i></button>
                </div>
            </header>
            <ul class="todo-content-list">
                
            </ul>
        </main>

매우 간단한 코드입니다.
input으로 받은 값을 ul태그 안에 li로 동적으로 생성하기 위해서
html로 고정해놓는 것이 아니라 javascript를 통한 생성을 할 것입니다.


javascript

class TodoEvent {
    static #instance = null;
    static getInstance() {
        if(this.#instance == null){
            this.#instance = new TodoEvent();
        }
        return this.#instance;
    }

    addEventAddTodoClick() {
      // todo를 추가하는 클릭버튼을 눌렀을 때 행동하는 로직입니다.
        const addTodoButton = document.querySelector('.add-todo-button');
        addTodoButton.onclick = () => {
            TodoService.getInstance().addTodo();
            const todoInput = document.querySelector('.todo-input');
            todoInput.value = '';
        }
    }

    addEventAddTodoKeyUp() {
      // 버튼대신 key 즉 enter키를 눌렀을 경우의 로직입니다.
        const todoInput = document.querySelector('.todo-input');
        todoInput.onkeyup = () => {
            if(window.event.keyCode == 13) {
                const addTodoButton = document.querySelector('.add-todo-button');
                addTodoButton.click();
            }
        } 
    }

    
    addEventRemoveTodoClick() {
      // todo가 생성이된 후 삭제를 시키는 버튼을 눌렀을 때 로직입니다.
        const removeButtons = document.querySelectorAll('.content-footer .remove-button');
        removeButtons.forEach((removeButton, index) => {
            removeButton.onclick = () => {
                ModalService.getInstance().showRemoveModal(index);
            }
        });
    }

    
    
    addEventModifyTodoClick() {
      // todo가 생성이 된 후 수정하는 버튼을 눌렀을 때 로직입니다.
        const modifyButtons = document.querySelectorAll('.content-footer .modify-button');
        modifyButtons.forEach((modifyButton, index) => {
            modifyButton.onclick = () => {
                ModalService.getInstance().showModifyModal(index);
                const modalModifyContent = document.querySelector('.modal-modify-content');
                const contents =TodoService.getInstance().todoList[index].todoContent;
                modalModifyContent.focus();
                modalModifyContent.value = contents;
            }
        });
    }

    addEventModifyTodoKeyUp() {
      // 버튼대신 enter키를 입력했을 경우입니다.
        const todoInput = document.querySelector('.modal-modify-content');
        todoInput.onkeyup = () => {
            if(window.event.keyCode == 13) {
                const modifyTodoButton = document.querySelector('.modal-ok-button');
                modifyTodoButton.click();
            }
        } 
    }
}

class TodoService {
    static #instance = null;
    static getInstance() {
        if(this.#instance == null){
            this.#instance = new TodoService();
        }
        return this.#instance;
    }
    
    todoList = null;
    constructor() {
      // service 클래스가 생성될 당시에 이루어질 기능들이다.
      // 로컬스토리지에 todoList라는 값이 null이면 
      // 새로운 배열을 생성해서 집어 넣어준다.
      // 하지만 아닐 경우 로컬 스토리지에 있는 값을 json 을 변환하여
      // todoList에 대입시켜준다.
        if(localStorage.getItem('todoList') == null) {
            this.todoList = new Array();
        }else {
            this.todoList = JSON.parse(localStorage.getItem('todoList'));
        }
        this.loadTodoList();
    }

    updateLocalStorage() {
      // 로컬스토리지를 업데이트 하는 과정입니다.
        localStorage.setItem('todoList', JSON.stringify(this.todoList));
        this.loadTodoList();
    }

    addTodo() {
      // todo를 더할 때 요일을 변환해야 하는데 그 로직이 convertDay의 로직입니다.
      
        const todoInput = document.querySelector('.todo-input');
        const nowDate = new Date();

        // console.log(`년 : ${nowDate.getFullYear()}`);
        // console.log(`월 : ${nowDate.getMonth()}`);
        // console.log(`일 : ${nowDate.getDate()}`);
        // console.log(`요일 : ${nowDate.getDay()}`);
        // console.log(`시 : ${nowDate.getHours()}`);
        // console.log(`분 : ${nowDate.getMinutes()}`);
        // console.log(`초 : ${nowDate.getSeconds()}`);

        const convertDay = (day) => {
            return day == 0 ? '일' :
                   day == 1 ? '월' :
                   day == 2 ? '화' :
                   day == 3 ? '수' :
                   day == 4 ? '목' :
                   day == 5 ? '금' : '토';
                   
        }
        
        const todoObj = {
            todoDate: `${nowDate.getFullYear()}.${nowDate.getMonth() + 1}.${nowDate.getDate()}(${convertDay(nowDate.getDay())})`,
            todoDateTime: `${nowDate.getHours()}:${nowDate.getMinutes()}:${nowDate.getSeconds()}`,
            todoContent: todoInput.value

        }

        this.todoList.push(todoObj);
        this.updateLocalStorage();
    }

    loadTodoList() {
      // todoList를 화면에 로드 시켜주는 로직입니다.
      // inner html 을 이용해서 todoList 배열을 반복을 돌면서
      // 해당 배열안에 있는 object들을 빼내와서 값을 대입해서 li를 만들어 줍니다.
        const todoContentList = document.querySelector('.todo-content-list');
        todoContentList.innerHTML = ``;
        this.todoList.forEach(todoObj => {
                todoContentList.innerHTML += `
                <li class="content-container">
                <div class="content-header">
                    <div class="todo-date">${todoObj.todoDate}</div>
                    <div class="todo-date-time">${todoObj.todoDateTime}</div>
                </div>
                <div class="content-main">
                   ${todoObj.todoContent}
                </div>
                <div class="content-footer">
                    <button class="modify-button">
                        <i class="fa-regular fa-pen-to-square"></i>
                    </button>
                    <button class="remove-button">
                        <i class="fa-regular fa-trash-can"></i>
                    </button>
                </div>
            </li>
                `;
            
        });
        TodoEvent.getInstance().addEventRemoveTodoClick();
        TodoEvent.getInstance().addEventModifyTodoClick();
        // TodoEvent.getInstance().addEventModifyTodoKeyUp();
    }
}

동적으로 html 코드가 변화하고 생성되어야 하기 때문에 inner html 을 사용하고
배열에 input으로 들어오는 값들을 저장하여 반복을 돌려서 화면에 뿌려주는 형식입니다.


마무리하며..

순수 자바스크립트를 이용해서 만들면서 귀찮은 코드들도 꽤나 많았던 것 같고
분명 반복을 처리하고 있는데 그안에 반복들이 있는 이상한 코드들도 꽤나 많았던 것 같다.
리액트로 변환하면서 새로운 라이브러리들과 달라지는 부분들을 소개해볼까 합니다.

profile
백엔드 개발자 준비중

0개의 댓글