Я никогда раньше не использовал ajax, но в моем текущем проекте я вижу в этом необходимость. У меня есть таблица счетов-фактур, в которой есть поле is_confirmed, для которого по умолчанию установлено значение false.
В index.blade.php я отобразил все счета, которые были отправлены текущим вошедшим в систему пользователем. В каждой строке таблицы, как только пользователь нажимает кнопку подтверждения, эта строка обновляется, и поле «is_confirmed» устанавливается в значение «true» в базе данных. Теперь проблема в том, что у них все еще активна кнопка подтверждения, что означает, что пользователь все еще может ее нажимать.
Как бы вы реализовали это так, чтобы для всех строк, для которых в поле «is_confirmed» установлено значение «true», кнопки будут отключены, а для тех строк, для которых в поле «is_confirmed» установлено значение «false», будут только те строки, у которых кнопка активируется даже при обновлении страницы.
Вот мой index.blade.php, который в настоящее время отображает все отправленные счета. Наряду с кнопкой подтверждения для обновления поля базы данных is_confirmed в каждой строке:
@section('content')
@foreach($sentinvoices as $sentinvoice)
<tr>
<td>
<span>{{ $sentinvoice->recipient->fullname }}</span>
</td>
<td>
<span>{{$sentinvoice->updated_at->format("M d, Y")}}</span>
</td>
<td>
<span>{{$sentinvoice->status}}</span>
</td>
<td>
<span>{{$sentinvoice->amount}}</span>
</td>
<td class = "text-center">
<form method = "POST" action = "{{ route('sender.confirm', $sentinvoice->uuid) }}" id = "ajax">
@csrf
<input type = "hidden" name = "sender_id" value = "{{$sentinvoice->sender_id}}">
<input type = "hidden" name = "is_confirmed" value = "{{$sentinvoice->is_confirmed}}">
<button class = "btn btn-success btn-sm" type = "submit" id = "confirm">Confirm</button>
</form>
</td>
</tr>
@endforeach
@endsection
Я также добавил функцию ajax в конец index.blade.php следующим образом:
@section('scripts')
<script src = "https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script>
$("#ajax").click(function(event) {
event.preventDefault();
$.ajax({
type: "post",
url: "{{ url('sender.confirm') }}",
dataType: "json",
data: $('#ajax').serialize(),
success: function(data){
alert("Data Save: " + data);
$("#confirm").prop('disabled', true);
},
error: function(data){
alert("Error")
}
});
});
</script>
@endsection
Вот моя функция в InvoiceController, которая отправляет форму:
public function confirmInvoice(Request $request, $uuid)
{
$user = auth()->user();
$sentinvoices = Invoice::where('uuid', $uuid)->first();
$sentinvoices->sender_id = $user->id;
$sentinvoices->is_confirmed = 1;
$sentinvoices->save();
return redirect()->back();
}
Я проверил ответы на другие похожие вопросы, но все равно не смог заставить это работать. Пожалуйста, помогите мне здесь.
Я обновил сообщение, добавив код, который отображает счета. Буду очень признателен за вашу помощь, спасибо.






Я предполагаю, что у вас есть форма для каждой кнопки подтверждения, поскольку вы этого не уточняете.
Прежде всего, ваша форма и кнопка подтверждения не могут иметь идентификатор #ajax.
и #confirm, потому что на
Идентификаторы страниц и элементов должны быть уникальными в пределах всего документа.
Поэтому замените это классом и удалите идентификатор на кнопке подтверждения, как показано ниже:
@section('content')
<form method = "POST" action = "{{ route('sender.confirm', $sentinvoice->uuid) }}" class = "confirm-form">
@csrf
<input type = "hidden" name = "sender_id" value = "{{$sentinvoice->sender_id}}">
<input type = "hidden" name = "sender_confirmed" value = "{{$sentinvoice->is_confirmed}}">
<button class = "btn btn-success btn-sm" type = "submit">Confirm</button></form>
@endsection
Затем в вашем запросе ajax замените идентификатор на имя класса, измените событие на отправку и используйте jQuery и $ (this) текущий элемент, чтобы найти кнопку внутри него и отключить опору.
$(".confirm-form").on('submit', function(event) {
event.preventDefault();
var $button = $(this).find('button');
var data = $(this).serialize();
$.ajax({
type: "post",
url: "{{ url('sender.confirm') }}",
dataType: "json",
data: data,
}).done(function () {
$button.prop('disabled', true)
});
});
Вот упрощенный рабочий пример:
$(".confirm-form").on('submit', function(event) {
event.preventDefault();
var $button = $(this).find('button');
var data = $(this).serialize();
$.ajax({
type: "post",
url: "https://jsonplaceholder.typicode.com/todos/",
dataType: "json",
data: data,
}).done(function () {
$button.prop('disabled', true)
});
});<script src = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td>Confirm 1</td>
<td>
<form class = "confirm-form">
<button>Confirm</button>
</form>
<td/>
</tr>
<tr>
<td>Confirm 2</td>
<td>
<form class = "confirm-form">
<button>Confirm</button>
</form>
<td/>
</tr>
<tr>
<td>Confirm 3</td>
<td>
<form class = "confirm-form">
<button>Confirm</button>
</form>
<td/>
</tr>
</table>Спасибо за ваш быстрый ответ. У меня нет формы для каждой кнопки подтверждения. Я отредактирую пост, чтобы прояснить это.
Вот пара вещей:
#ajax на самом деле является идентификатором формы, вы не можете «щелкнуть» по форме, а вместо этого отправляете ее.Вот пример того, что вы можете сделать:
Вид:
@section('content')
<form method = "POST" action = "{{ route('sender.confirm', $sentinvoice->uuid) }}" id = "form-{{$sentinvoice->uuid}}" class='ajax'>
@csrf
<input type = "hidden" name = "sender_id" value = "{{$sentinvoice->sender_id}}">
<input type = "hidden" name = "is_confirmed" value = "{{$sentinvoice->is_confirmed}}">
<button class = "btn btn-success btn-sm" type = "submit" class = "confirm" {!! $sentinvoice->is_confirmed ? 'disabled = "disabled"' : '' !!}>Confirm</button>
</form>
@endsection
JavaScript
@section('scripts')
<script src = "https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script>
$(".ajax").submit(function(event) { //listening on class name and for submit action
event.preventDefault();
var $confirmButton = $(this).find('.confirm'); // the confirm button of this form
$confirmButton.prop('disabled', true);
$.ajax({
type: "post",
url: $(this).attr('action'), //send to the correct url based on the markup
dataType: "json",
data: $(this).serialize(), //this refers to the submitted form
success: function(data){
alert("Data Saved");
},
error: function(data){
$confirmButton.prop('disabled', false);
alert("Error")
}
});
});
</script>
@endsection
И ваш контроллер:
public function confirmInvoice(Request $request, $uuid)
{
$user = auth()->user();
$sentinvoices = Invoice::where('uuid', $uuid)->first();
$sentinvoices->sender_id = $user->id;
$sentinvoices->is_confirmed = 1;
if (!$sentinvoices->save()) {
return response()->json([ 'success' => false ], 500); //Error response
}
return response()->json([ 'success' => true ]);
}
Что изменилось:
submit вместо события щелчка. Здесь будут рассмотрены альтернативные способы отправки формы (например, путем перехода к кнопке и нажатия клавиши ввода).Обратите внимание, что кнопка подтверждения здесь отключена перед отправкой запроса и активируется только в случае сбоя запроса. Это предотвратит повторное нажатие на нее до того, как запрос будет выполнен.
Спасибо за подробный ответ. Я пытаюсь не только предотвратить нажатие кнопки до того, как запрос будет выполнен. Моя проблема в том, что после выполнения запроса кнопка становится доступной для нажатия при обновлении страницы даже для строк, которые были ранее подтверждены. Подумайте об этом так: когда пользователь посещает эту страницу, кнопка подтверждения должна быть активна только для счетов, которые они еще не подтвердили. На всех подтвержденных счетах не должно быть активной кнопки.
@Ehi попробуйте обновить, это должно быть решено установкой атрибута disabled = "disabled" на кнопке на основе начального значения модели.
Большое спасибо, это сработало! Я очень благодарен за помощь @apokryfos. Спасибо всем, кто нашел время, чтобы помочь, я ценю.
Где код, который отображает
invoices?