Очередность действий js
помогите решить проблему. Есть задача, имеются какие-то строки выведенные в html через php. Нужно сделать кнопку удаления, с подтверждением удаления через ajax. И вот что у меня получилось:
Код js:
$('.form-btn-delete-confirm').click(function (e) {
$(this).clearQueue();
// TODO: починить
e.preventDefault();
let uri = null;
let id = null;
uri = $(this).attr('action');
id = $(this).attr('data-id');
let response;
console.log('click-delete');
$('#btn-delete-confirm').click(function () {
console.log('click-confirm');
$.ajax({
url: `${uri}`,
type: 'DELETE',
headers: {
'X-CSRF-TOKEN': csrfToken
},
success: (data) => {
console.log('success');
$('#modal-delete-confirm').modal('hide');
response = data;
$(`tr[data-id="${id}"]`).remove();
notyf.success({
message: response.message
});
},
error: (data) => {
console.log('error');
$('#modal-delete-confirm').modal('hide');
response = data.responseJSON;
notyf.error({
message: response.message
});
}
});
});
});
В коде я поставил чекпоинты с выводом в консоль, чтобы смотреть, где сейчас код отрабатывает.
И вот такой код laravel.blade.php
<td class="border-0 align-middle">
<a href="{{ route('nomenclatures.edit', $nomenclature['id']) }}">
<button class="btn btn-sm btn-secondary" type="button">Редактировать</button>
</a>
<form action="{{ route('nomenclatures.destroy', $nomenclature['id']) }}" data-id="{{ $nomenclature['id'] }}" class="form-btn-delete-confirm" method="POST"
style="display: inline-block">
@csrf
@method('DELETE')
<button class="btn btn-sm btn-danger" type="submit" data-bs-toggle="modal" data-bs-target="#modal-delete-confirm">Удалить</button>
</form>
</td>
<div class="modal fade" id="modal-delete-confirm" tabindex="-1" role="dialog" aria-labelledby="modal-delete-confirm" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h2 class="h6 modal-title">Удаление</h2>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<p>Подтвердите удаление</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" id="btn-delete-confirm">Удалить</button>
<button type="button" class="btn btn-link text-gray ms-auto" data-bs-dismiss="modal">Закрыть</button>
</div>
</div>
</div>
</div>
У меня это работает, если нажать кнопку отмены, то удаление отменяется. Но если отменить допустим 3 раза, а на 4 раз подтвердить, то 1 раз удалится, и 3 раза выдаст ошибку о том, что такого элемента не существует. Почему так? Я полагаю, что отмененные действия как-то сохраняются и применяются когда произошло событие клика на кнопку подтверждения и я не знаю как это исправить.
Вот скрин консоли, ниже опишу мои действия
Я 2 раза нажимаю на .form-btn-delete-confirm и оба раза в модальном окне отменяю удаление.
Далее, я нажимаю еще раз на .form-btn-delete-confirm и подтверждаю удаление нажатием нажатием на #btn-delete-confirm и в консоли видно, как будто я 3 раза нажал на #btn-delete-confirm. И соответственно произошло 3 ajax запроса. 1 успех и 2 неудачи, так как этого элементе в БД уже нет.
Что мне с этим делать?
Ответы (1 шт):
Видимо дело в том что при каждом нажатии на .form-btn-delete-confirm, в обработчике Вы создаёте каждый раз ещё один обработчик уже для #btn-delete-confirm, таким образом несколько нажатий на .form-btn-delete-confirm зарегистрирует несколько обработчиков #btn-delete-confirm, при нажатии на который у Вас отработают зарегистрированные ранее обработчики. Соответственно 3 нажатия на .form-btn-delete-confirm порождает 3 обработчика #btn-delete-confirm, и теперь при нажатии на #btn-delete-confirm, сработают эти три обработчика и каждый выполнить этот код. Соответственно первый раз ajax удалит, а оставшиеся уже не найдут эту запись и вернут 404.
Исходя из выше сказанного необходимо вынести регистрацию обработчика #btn-delete-confirm, из обработчика .form-btn-delete-confirm Например вот так:
$('.form-btn-delete-confirm').click(function (e) {
$(this).clearQueue();
// TODO: починить
e.preventDefault();
let uri = null;
let id = null;
uri = $(this).attr('action');
id = $(this).attr('data-id');
let response;
console.log('click-delete');
});
$('#btn-delete-confirm').click(function () {
console.log('click-confirm');
$.ajax({
url: `${uri}`,
type: 'DELETE',
headers: {
'X-CSRF-TOKEN': csrfToken
},
success: (data) => {
console.log('success');
$('#modal-delete-confirm').modal('hide');
response = data;
$(`tr[data-id="${id}"]`).remove();
notyf.success({
message: response.message
});
},
error: (data) => {
console.log('error');
$('#modal-delete-confirm').modal('hide');
response = data.responseJSON;
notyf.error({
message: response.message
});
}
});
});
