Laravel и Ajax - отключить кнопку отправки, если поле столбца истинно

Я никогда раньше не использовал ajax, но в моем текущем проекте я вижу в этом необходимость. У меня есть таблица счетов-фактур, в которой есть поле is_confirmed, для которого по умолчанию установлено значение false.

В index.blade.php я отобразил все счета, которые были отправлены текущим вошедшим в систему пользователем. В каждой строке таблицы, как только пользователь нажимает кнопку подтверждения, эта строка обновляется, и поле «is_confirmed» устанавливается в значение «true» в базе данных. Теперь проблема в том, что у них все еще активна кнопка подтверждения, что означает, что пользователь все еще может ее нажимать.

Как бы вы реализовали это так, чтобы для всех строк, для которых в поле «is_confirmed» установлено значение «true», кнопки будут отключены, а для тех строк, для которых в поле «is_confirmed» установлено значение «false», будут только те строки, у которых кнопка активируется даже при обновлении страницы.

Вот отображаемая таблица: Laravel и Ajax - отключить кнопку отправки, если поле столбца истинно

Вот мой 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();
    }

Я проверил ответы на другие похожие вопросы, но все равно не смог заставить это работать. Пожалуйста, помогите мне здесь.

Где код, который отображает invoices?

thisiskelvin 21.09.2018 15:16

Я обновил сообщение, добавив код, который отображает счета. Буду очень признателен за вашу помощь, спасибо.

Ehi 21.09.2018 15:44
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
2
1 977
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Я предполагаю, что у вас есть форма для каждой кнопки подтверждения, поскольку вы этого не уточняете.

Прежде всего, ваша форма и кнопка подтверждения не могут иметь идентификатор #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>

Спасибо за ваш быстрый ответ. У меня нет формы для каждой кнопки подтверждения. Я отредактирую пост, чтобы прояснить это.

Ehi 21.09.2018 15:26
Ответ принят как подходящий

Вот пара вещей:

  1. Поскольку вы делаете запрос AJAX, ответ на перенаправление не имеет никакого смысла.
  2. Ваш идентификатор #ajax на самом деле является идентификатором формы, вы не можете «щелкнуть» по форме, а вместо этого отправляете ее.
  3. Поскольку у вас, вероятно, есть несколько форм, вы должны дать каждой из них уникальный идентификатор и отслеживать события отправки для всех из них.

Вот пример того, что вы можете сделать:

Вид:

@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 ]); 
}

Что изменилось:

  1. Идентификаторы уникальны (и не очень важны), но мы слушаем события в классах. Это потому, что JavaScript требует, чтобы идентификаторы были уникальными.
  2. Мы слушаем событие submit вместо события щелчка. Здесь будут рассмотрены альтернативные способы отправки формы (например, путем перехода к кнопке и нажатия клавиши ввода).
  3. Контроллер вернет JSON и соответствующий код ответа.

Обратите внимание, что кнопка подтверждения здесь отключена перед отправкой запроса и активируется только в случае сбоя запроса. Это предотвратит повторное нажатие на нее до того, как запрос будет выполнен.

Спасибо за подробный ответ. Я пытаюсь не только предотвратить нажатие кнопки до того, как запрос будет выполнен. Моя проблема в том, что после выполнения запроса кнопка становится доступной для нажатия при обновлении страницы даже для строк, которые были ранее подтверждены. Подумайте об этом так: когда пользователь посещает эту страницу, кнопка подтверждения должна быть активна только для счетов, которые они еще не подтвердили. На всех подтвержденных счетах не должно быть активной кнопки.

Ehi 21.09.2018 16:09

@Ehi попробуйте обновить, это должно быть решено установкой атрибута disabled = "disabled" на кнопке на основе начального значения модели.

apokryfos 21.09.2018 16:11

Большое спасибо, это сработало! Я очень благодарен за помощь @apokryfos. Спасибо всем, кто нашел время, чтобы помочь, я ценю.

Ehi 21.09.2018 16:49

Другие вопросы по теме