본문 바로가기
Frontend/Javascript

[Javascript] Javascript 예제(심화) - 수정

by cogito21_js 2024. 6. 8.
반응형

UI 디자인을 개선하고, 코드에서 수정된 부분에 대한 메시지를 추가하겠습니다.

개선된 UI 디자인

HTML 코드

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Advanced To-Do List</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <div class="todo-container">
        <h1>Advanced To-Do List</h1>
        <div class="input-container">
            <input type="text" id="todo-input" placeholder="Enter a new task">
            <button id="add-todo">Add</button>
        </div>
        <div class="filter-container">
            <select id="filter-todos">
                <option value="all">All</option>
                <option value="completed">Completed</option>
                <option value="uncompleted">Uncompleted</option>
            </select>
            <button id="clear-all">Clear All</button>
        </div>
        <ul id="todo-list"></ul>
    </div>
    <script src="script.js"></script>
</body>
</html>

CSS 코드

/* styles.css */
body {
    font-family: Arial, sans-serif;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    margin: 0;
    background-color: #f0f0f0;
}

.todo-container {
    background-color: #fff;
    padding: 20px;
    border-radius: 8px;
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
    width: 400px;
    text-align: center;
}

h1 {
    margin-bottom: 20px;
    font-size: 24px;
    color: #333;
}

.input-container, .filter-container {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 10px;
}

input[type="text"] {
    flex: 1;
    padding: 10px;
    margin-right: 10px;
    border: 1px solid #ddd;
    border-radius: 4px;
}

button {
    padding: 10px 20px;
    border: none;
    border-radius: 4px;
    background-color: #4CAF50;
    color: white;
    cursor: pointer;
}

button#clear-all {
    background-color: #f44336;
}

ul {
    list-style-type: none;
    padding: 0;
    margin: 0;
}

li {
    padding: 10px;
    border-bottom: 1px solid #ddd;
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 10px;
}

li.completed {
    text-decoration: line-through;
    color: #888;
}

li button {
    background-color: #2196F3;
    border: none;
    border-radius: 4px;
    color: white;
    padding: 5px 10px;
    cursor: pointer;
    margin-left: 5px;
}

li button.delete {
    background-color: #f44336;
}

li button.complete {
    background-color: #4CAF50;
}

select {
    padding: 10px;
    border: 1px solid #ddd;
    border-radius: 4px;
}

JavaScript 코드

// script.js
document.addEventListener('DOMContentLoaded', loadTasks);

document.getElementById('add-todo').addEventListener('click', function() {
    let input = document.getElementById('todo-input');
    let newTask = input.value;

    if (newTask !== '') {
        addTask(newTask);
        input.value = '';
    }
});

document.getElementById('todo-input').addEventListener('keypress', function(event) {
    if (event.key === 'Enter') {
        document.getElementById('add-todo').click();
    }
});

document.getElementById('clear-all').addEventListener('click', clearAllTasks);

document.getElementById('filter-todos').addEventListener('change', filterTasks);

function addTask(task, completed = false) {
    let li = document.createElement('li');
    li.textContent = task;

    if (completed) {
        li.classList.add('completed');
    }

    let editButton = document.createElement('button');
    editButton.textContent = 'Edit';
    editButton.classList.add('edit');
    editButton.addEventListener('click', function() {
        let newTask = prompt('Edit task:', li.firstChild.textContent);
        if (newTask !== null && newTask !== '') {
            li.firstChild.textContent = newTask;
            saveTasks();
        }
    });

    let deleteButton = document.createElement('button');
    deleteButton.textContent = 'Delete';
    deleteButton.classList.add('delete');
    deleteButton.addEventListener('click', function() {
        li.remove();
        saveTasks();
    });

    let completeButton = document.createElement('button');
    completeButton.textContent = 'Complete';
    completeButton.classList.add('complete');
    completeButton.addEventListener('click', function() {
        li.classList.toggle('completed');
        saveTasks();
    });

    li.appendChild(editButton);
    li.appendChild(completeButton);
    li.appendChild(deleteButton);
    document.getElementById('todo-list').appendChild(li);
    saveTasks();
}

function saveTasks() {
    let tasks = [];
    document.querySelectorAll('#todo-list li').forEach(li => {
        tasks.push({
            text: li.firstChild.textContent,
            completed: li.classList.contains('completed')
        });
    });
    localStorage.setItem('tasks', JSON.stringify(tasks));
}

function loadTasks() {
    let tasks = JSON.parse(localStorage.getItem('tasks')) || [];
    tasks.forEach(task => addTask(task.text, task.completed));
}

function clearAllTasks() {
    document.getElementById('todo-list').innerHTML = '';
    localStorage.removeItem('tasks');
}

function filterTasks() {
    let filter = document.getElementById('filter-todos').value;
    document.querySelectorAll('#todo-list li').forEach(li => {
        switch (filter) {
            case 'all':
                li.style.display = 'flex';
                break;
            case 'completed':
                if (li.classList.contains('completed')) {
                    li.style.display = 'flex';
                } else {
                    li.style.display = 'none';
                }
                break;
            case 'uncompleted':
                if (!li.classList.contains('completed')) {
                    li.style.display = 'flex';
                } else {
                    li.style.display = 'none';
                }
                break;
        }
    });
}

주요 수정 사항 및 설명

  1. HTML 코드 수정:

    • Input과 Add 버튼을 감싸는 div.input-container를 추가하여 더 나은 레이아웃을 제공.
    • Filter와 Clear All 버튼을 감싸는 div.filter-container를 추가하여 UI를 개선.
  2. CSS 코드 수정:

    • Input과 버튼flex 레이아웃을 사용하여 정렬 및 배치를 개선.
    • Filter와 Clear All 버튼에도 동일한 flex 레이아웃을 적용.
    • 할 일 항목의 각 버튼을 다른 색상으로 변경하여 구분을 명확히 함.
  3. JavaScript 코드 수정:

    • addTask 함수에 completed 인수를 추가하여, 로드된 할 일 항목의 완료 상태를 유지.
    • CSS 클래스 이름에 따라 각 버튼의 스타일을 추가로 지정.
반응형