Skip to content

How to prevent form re submission in Laravel

Server-Side Solution:

In your controller’s method (that handles input data in a form i.e; Create/Preview), you can generate a one-time token and store it in the session. When the form is submitted, validate this token. If the token is valid, remove it from the session. If the token is not valid, it means the form has already been submitted. In our case we are using a Preview method.

public function invoicePreview(Request $request)
{
     // Generate a one-time token
     $token = uniqid();
     
     // Store the token in the session
     $request->session()->put('invoice_token', $token);
     // ... rest of your code

     return view('operations.orders.preview_invoice')->with([
          'customer_data' => $customer_data,
          //... rest of your data
          'invoice_token' => $token, // Pass the token to the view
     ]);
}

In your form, include the token as a hidden input. We are using the preview form mentioned earlier.

<form class="form-horizontal" name="requestForm" id="requestForm" method="post" action="{{ route('store-invoice')}}">
@csrf
    <input type="hidden" name="invoice_token" value="{{ $invoice_token }}">
    <!-- rest of your form -->
</form>

In your store method, validate the token. For us, the method is called storeInvoice() that takes the form request & handles the data processing & stores in the database.

public function storeInvoice(Request $request)
{
     // Validate the token
     $token = $request->input('invoice_token');
     if ($token && $request->session()->get('invoice_token') === $token) {
          // Token is valid, remove it from the session
          $request->session()->forget('invoice_token');
          // Process the form submission
          // ...
     } else {
          // Token is not valid, form has already been submitted
          return redirect()->route('page-expired');
     }
}

Client-Side Solution:

Additionally, you can use JavaScript to disable the form submission button after it’s clicked, preventing multiple submissions.

<script>
     document.addEventListener('DOMContentLoaded', function () {
          document.getElementById('submit-button').addEventListener('click', function () {
          this.setAttribute('disabled', 'disabled');
          });
     });
</script>

Create a Page Expired blade
Create a new view named expired_page.blade.php

 to display the expired page message. In our case, a form re submission will trigger 

return redirect()->route('page-expired'); & the page-expired will be displayed. We have added the feature of automatically redirecting this page to the dashboard using javascript as an added feature.

@section('content')
     <!-- Content Wrapper. Contains page content -->
     <div class="content-wrapper">
          <div class="content p-1">
                <div class="row">
                     <div class="col-4">
                          @include('flash-message')
                     </div>
                </div>
          <div class="mt-5 d-flex justify-content-center align-items-center">
               <div class="card col-md-4 bg-white shadow-md p-5">
                    <div class="mb-4 text-center">
                         <span><i class="mdi mdi-format-page-break text-danger" style="font-size: 10rem;"></i></span>
                    </div>
                    <div class="text-center">
                          <h1>This page is expired!</h1>
                          <p>You will be redirected to the Dashboard automatically in <br><span class="text-success" id="countdown" style="font-size: 2rem">5</span> seconds.</p>
                          <a href="{{ route('home') }}" class="btn btn-outline-success">Back Home</a>
                    </div>
              </div>
        </div>
     </div>
</div>
<!-- /.content-wrapper -->
@endsection
@section('scripts')
<script>
     // Countdown timer
     let seconds = 5;
     const countdownElement = document.getElementById('countdown');
     function updateCountdown() {
           countdownElement.textContent = seconds;
           if (seconds <= 0) {
           window.location.href = "{{ route('home') }}";
           } 
           else {
               seconds--;
               setTimeout(updateCountdown, 1000);
           }
     }
     // Start the countdown
     updateCountdown();
</script>
@endsection

Create a controller method to access the Page:

In our case we have created the method in TransactionController:

public function pageExpired(){
     return view('operations.expired-page');
}

Add Expired Page Route:

In your web.php file or route file:

Route::get('/page-expired',[TransactionController::class,'pageExpired'])->name('page-expired');

Leave a Reply

Your email address will not be published. Required fields are marked *