Implement proper AJAX handling for subtasks
- Fix DOM manipulation to handle empty subtasks list - Create subtasks list dynamically if it doesn't exist - Update UI elements without page reload - Handle all edge cases for add/delete/toggle operations
This commit is contained in:
parent
bf609257c3
commit
c94f21b01e
|
|
@ -246,8 +246,50 @@ function addSubtask(event, taskId) {
|
|||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
// Обновляем страницу вместо манипуляций с DOM
|
||||
location.reload();
|
||||
// Находим контейнер для подзадач
|
||||
let list = document.getElementById('subtasks-list');
|
||||
|
||||
// Если списка ещё нет (был пустой), создаём его
|
||||
if (!list) {
|
||||
const cardBody = form.closest('.card-body');
|
||||
const emptyMessage = cardBody.querySelector('p.text-muted.text-center');
|
||||
|
||||
// Создаём новый список подзадач
|
||||
const newList = document.createElement('ul');
|
||||
newList.className = 'list-group list-group-flush mb-3';
|
||||
newList.id = 'subtasks-list';
|
||||
|
||||
// Вставляем перед формой
|
||||
cardBody.insertBefore(newList, form);
|
||||
|
||||
// Удаляем сообщение "Подзадач пока нет"
|
||||
if (emptyMessage) {
|
||||
emptyMessage.remove();
|
||||
}
|
||||
|
||||
list = newList;
|
||||
}
|
||||
|
||||
// Создаём новую подзадачу
|
||||
const newItem = document.createElement('li');
|
||||
newItem.className = 'list-group-item d-flex align-items-center gap-2';
|
||||
newItem.setAttribute('data-subtask-id', data.subtask_id);
|
||||
newItem.innerHTML = `
|
||||
<input type="checkbox" class="form-check-input subtask-checkbox" onchange="toggleSubtask(${taskId}, ${data.subtask_id})">
|
||||
<span class="flex-grow-1">${title}</span>
|
||||
<button type="button" class="btn btn-outline-danger btn-sm" onclick="deleteSubtask(${taskId}, ${data.subtask_id})" title="Удалить">
|
||||
<i class="fa-solid fa-times"></i>
|
||||
</button>
|
||||
`;
|
||||
|
||||
// Добавляем в список
|
||||
list.appendChild(newItem);
|
||||
|
||||
// Очищаем поле ввода
|
||||
input.value = '';
|
||||
|
||||
// Обновляем счётчик
|
||||
updateSubtasksCount();
|
||||
} else {
|
||||
alert(data.error || 'Ошибка при создании подзадачи');
|
||||
}
|
||||
|
|
@ -259,9 +301,15 @@ function addSubtask(event, taskId) {
|
|||
}
|
||||
|
||||
function updateSubtasksCount() {
|
||||
const count = document.querySelectorAll('#subtasks-list li').length;
|
||||
const completed = document.querySelectorAll('#subtasks-list li input:checked').length;
|
||||
const badge = document.querySelector('#subtasks-list ~ .badge');
|
||||
const list = document.getElementById('subtasks-list');
|
||||
if (!list) return;
|
||||
|
||||
const items = list.querySelectorAll('li');
|
||||
const count = items.length;
|
||||
const completed = list.querySelectorAll('li input:checked').length;
|
||||
|
||||
// Обновляем счётчик на заголовке карточки
|
||||
const badge = document.querySelector('.card-header h5 .badge');
|
||||
if (badge) {
|
||||
badge.textContent = `${completed}/${count}`;
|
||||
}
|
||||
|
|
@ -281,8 +329,20 @@ function toggleSubtask(taskId, subtaskId) {
|
|||
if (!data.success) {
|
||||
alert(data.error || 'Ошибка');
|
||||
} else {
|
||||
// Обновляем страницу для обновления UI
|
||||
location.reload();
|
||||
// Находим чекбокс и обновляем состояние
|
||||
const checkbox = document.querySelector(`[data-subtask-id="${subtaskId}"] .subtask-checkbox`);
|
||||
const span = checkbox.nextElementSibling;
|
||||
|
||||
if (checkbox.checked) {
|
||||
checkbox.checked = false;
|
||||
span.classList.remove('text-muted', 'text-decoration-line-through');
|
||||
} else {
|
||||
checkbox.checked = true;
|
||||
span.classList.add('text-muted', 'text-decoration-line-through');
|
||||
}
|
||||
|
||||
// Обновляем счётчик
|
||||
updateSubtasksCount();
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
|
|
@ -306,8 +366,27 @@ function deleteSubtask(taskId, subtaskId) {
|
|||
if (!data.success) {
|
||||
alert(data.error || 'Ошибка');
|
||||
} else {
|
||||
// Обновляем страницу для обновления UI
|
||||
location.reload();
|
||||
// Удаляем из DOM
|
||||
const item = document.querySelector(`li[data-subtask-id="${subtaskId}"]`);
|
||||
if (item) {
|
||||
item.remove();
|
||||
|
||||
// Если список пуст, показываем сообщение
|
||||
const list = document.getElementById('subtasks-list');
|
||||
if (list && list.children.length === 0) {
|
||||
list.remove();
|
||||
|
||||
// Добавляем сообщение "Подзадач пока нет"
|
||||
const cardBody = item.closest('.card-body');
|
||||
const message = document.createElement('p');
|
||||
message.className = 'text-muted text-center mb-3';
|
||||
message.textContent = 'Подзадач пока нет';
|
||||
cardBody.appendChild(message);
|
||||
}
|
||||
|
||||
// Обновляем счётчик
|
||||
updateSubtasksCount();
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
|
|
|
|||
Loading…
Reference in New Issue