View difference between Paste ID: sEhfj3Fk and tWG3t2Tq
SHOW: | | - or go back to the newest paste.
1
<!DOCTYPE html>
2
<html lang="pl">
3
<head>
4
    <meta charset="UTF-8">
5
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
    <title>To-Do List</title>
7
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
8
</head>
9
<body>
10
11
<div class="container mt-5">
12
    <div class="row">
13
        <div class="col-md-8 offset-md-2">
14
            <div class="card">
15
                <div class="card-header bg-primary text-white text-center">
16
                    <h3>To-Do List</h3>
17
                </div>
18
                <div class="card-body">
19
                    <form id="todoForm" class="mb-3">
20
                        <div class="input-group">
21
                            <input type="text" class="form-control" id="taskInput" placeholder="Enter new task" required>
22
                            <button type="submit" class="btn btn-primary">Add Task</button>
23
                        </div>
24
                    </form>
25
                    <div id="alertPlaceholder"></div>
26
                    <ul class="list-group" id="taskList">
27
                        <!-- Zadania będą dodawane tutaj dynamicznie -->
28
                    </ul>
29
                    <div class="mt-3">
30
                        <div class="progress">
31
                            <div id="progressBar" class="progress-bar" role="progressbar" style="width: 0%;" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">0%</div>
32
                        </div>
33
                    </div>
34
                </div>
35
            </div>
36
        </div>
37
    </div>
38
</div>
39
40
<!-- Modal do edycji zadania -->
41
<div class="modal fade" id="editTaskModal" tabindex="-1" aria-labelledby="editTaskModalLabel" aria-hidden="true">
42
    <div class="modal-dialog">
43
        <div class="modal-content">
44
            <div class="modal-header">
45
                <h5 class="modal-title" id="editTaskModalLabel">Edit Task</h5>
46
                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
47
            </div>
48
            <div class="modal-body">
49
                <form id="editTaskForm">
50
                    <div class="mb-3">
51
                        <label for="editTaskInput" class="form-label">Task</label>
52
                        <input type="text" class="form-control" id="editTaskInput" required>
53
                    </div>
54
                    <button type="submit" class="btn btn-primary">Save changes</button>
55
                </form>
56
            </div>
57
        </div>
58
    </div>
59
</div>
60
61
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
62
<script>
63
    document.addEventListener('DOMContentLoaded', () => {
64
        // Pobranie elementów z DOM
65
        const taskForm = document.getElementById('todoForm'); // Formularz do dodawania zadań
66
        const taskInput = document.getElementById('taskInput'); // Pole tekstowe do wprowadzania zadania
67
        const taskList = document.getElementById('taskList'); // Lista zadań
68
        const progressBar = document.getElementById('progressBar'); // Pasek postępu
69
        const alertPlaceholder = document.getElementById('alertPlaceholder'); // Miejsce na alerty
70
        const editTaskModal = new bootstrap.Modal(document.getElementById('editTaskModal')); // Modal do edycji zadań
71
        const editTaskForm = document.getElementById('editTaskForm'); // Formularz w modal
72
        const editTaskInput = document.getElementById('editTaskInput'); // Pole tekstowe w modal
73
        let currentEditTaskItem = null; // Zmienna przechowująca aktualnie edytowane zadanie
74
75
        // Obsługa zdarzenia 'submit' formularza dodawania zadań
76
        taskForm.addEventListener('submit', (e) => {
77
            e.preventDefault(); // Zatrzymanie domyślnego działania formularza
78
            const taskText = taskInput.value.trim(); // Pobranie i przycięcie wartości z pola tekstowego
79
            if (taskText !== '') {
80
                addTask(taskText); // Dodanie zadania
81
                taskInput.value = ''; // Wyczyść pole tekstowe
82
                showAlert('Task added successfully!', 'success'); // Pokaż alert sukcesu
83
            } else {
84
                showAlert('Task cannot be empty!', 'danger'); // Pokaż alert błędu
85
            }
86
        });
87
88
        // Funkcja dodająca zadanie do listy
89
        function addTask(taskText) {
90
            const taskItem = document.createElement('li'); // Stworzenie nowego elementu listy
91
            taskItem.className = 'list-group-item d-flex justify-content-between align-items-center'; // Dodanie klas Bootstrap
92
            taskItem.innerHTML = `
93
        <span>${taskText}</span>
94
        <div>
95
            <button class="btn btn-success btn-sm me-2 complete-btn">Complete</button>
96
            <button class="btn btn-secondary btn-sm me-2 edit-btn">Edit</button>
97
            <button class="btn btn-danger btn-sm delete-btn">Delete</button>
98
        </div>
99
        `;
100
            taskList.appendChild(taskItem); // Dodanie zadania do listy
101
102
            // Obsługa przycisku 'Complete'
103
            const completeBtn = taskItem.querySelector('.complete-btn');
104
            completeBtn.addEventListener('click', () => {
105
                taskItem.classList.toggle('completed'); // Zmiana stanu ukończenia zadania
106
                completeBtn.textContent = taskItem.classList.contains('completed') ? 'Undo' : 'Complete'; // Zmiana tekstu przycisku
107
                updateProgressBar(); // Aktualizacja paska postępu
108
            });
109
110
            // Obsługa przycisku 'Edit'
111
            const editBtn = taskItem.querySelector('.edit-btn');
112
            editBtn.addEventListener('click', () => {
113
                currentEditTaskItem = taskItem; // Ustawienie aktualnie edytowanego zadania
114
                editTaskInput.value = taskText; // Ustawienie wartości w polu tekstowym modala
115
                editTaskModal.show(); // Pokazanie modala
116
            });
117
118
            // Obsługa przycisku 'Delete'
119
            const deleteBtn = taskItem.querySelector('.delete-btn');
120
            deleteBtn.addEventListener('click', () => {
121
                taskList.removeChild(taskItem); // Usunięcie zadania z listy
122
                updateProgressBar(); // Aktualizacja paska postępu
123
                showAlert('Task deleted successfully!', 'success'); // Pokaż alert sukcesu
124
            });
125
        }
126
127
        // Obsługa zdarzenia 'submit' formularza edycji zadania
128
        editTaskForm.addEventListener('submit', (e) => {
129
            e.preventDefault(); // Zatrzymanie domyślnego działania formularza
130
            if (currentEditTaskItem) {
131
                const newTaskText = editTaskInput.value.trim(); // Pobranie i przycięcie wartości z pola tekstowego
132
                if (newTaskText !== '') {
133
                    currentEditTaskItem.querySelector('span').textContent = newTaskText; // Aktualizacja tekstu zadania
134
                    editTaskModal.hide(); // Ukrycie modala
135
                    showAlert('Task updated successfully!', 'success'); // Pokaż alert sukcesu
136
                } else {
137
                    showAlert('Task cannot be empty!', 'danger'); // Pokaż alert błędu
138
                }
139
            }
140
        });
141
142
        // Funkcja aktualizująca pasek postępu
143
        function updateProgressBar() {
144
            const totalTasks = taskList.children.length; // Liczba wszystkich zadań
145
            const completedTasks = taskList.querySelectorAll('.completed').length; // Liczba ukończonych zadań
146
            const completionRate = totalTasks === 0 ? 0 : (completedTasks / totalTasks) * 100; // Obliczenie procentu ukończenia
147
            progressBar.style.width = `${completionRate}%`; // Ustawienie szerokości paska postępu
148
            progressBar.setAttribute('aria-valuenow', completionRate); // Ustawienie wartości aria
149
            progressBar.textContent = `${Math.round(completionRate)}%`; // Ustawienie tekstu paska postępu
150
        }
151
152
        // Funkcja pokazująca alert
153
        function showAlert(message, type) {
154
            const alert = document.createElement('div'); // Stworzenie nowego elementu alertu
155
            alert.className = `alert alert-${type} alert-dismissible fade show`; // Dodanie klas Bootstrap
156
            alert.role = 'alert'; // Ustawienie roli
157
            alert.innerHTML = `
158
        ${message}
159
        <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
160
        `;
161
            alertPlaceholder.appendChild(alert); // Dodanie alertu do placeholdera
162
            setTimeout(() => {
163
                if (alert) {
164
                    alert.classList.remove('show'); // Usunięcie klasy 'show'
165
                    alert.classList.add('fade'); // Dodanie klasy 'fade'
166
                    setTimeout(() => alert.remove(), 150); // Usunięcie alertu po krótkim czasie
167
                }
168
            }, 3000); // Czas trwania alertu
169
        }
170
    });
171
172
</script>
173
174
<style>
175
    .completed {
176
        text-decoration: line-through;
177
        color: grey;
178
    }
179
</style>
180
181
</body>
182
</html>
183