How to Add to Cart in Laravel

by Vincy. Last modified on March 17th, 2024.

This tutorial is to create a shopping cart in Laravel. It shows how to add a product to a shopping cart. This is as simple as it gets. It will be a starter program who wants to get into writing a fullfledged shopping cart in PHP Laravel.

This example manages the cart items in a session. It shows a product gallery with the add-to-cart button on the welcome page.

view demo

This code gives a simple shopping cart interface that allows add-to-cart from multiple places.

  • It contains the add-to-cart button in the gallery and product view page.
  • It also supports bulk add-to-cart by entering one or more product codes.

Steps to have shopping cart add-to-cart feature in Laravel

  1. Build product data source in Laravel app config.
  2. Create shopping cart web route URLs.
  3. Design Laravel templates with add-to-cart options.
  4. Register event handlers to perform product search and cart actions.
  5. Manage cart items in session via app controllers.

add to cart in laravel

1. Build product data array in Laravel app config

This example keeps the product data in a config file. In a real-time application, it will be from the database. In a previous tutorial, we have already seen how to load products into a Laravel shopping cart from the database.

config/products.php

<?php
return [
    'H123' => [
        'name' => 'On-Ear Headphone BT v8.1',
        'code' => 'H123',
        'price' => 19.99,
        'image_path' => 'storage/products/headphone.jpg',
    ],
    'C456' =>  [
        'name' => 'Mirrorless Digital Camera',
        'code' => 'C456',
        'price' => 29.99,
        'image_path' => 'storage/products/camera.jpg',
    ],
    'W789' =>  [
        'name' => 'Quartz Analog Black Dial Watch',
        'code' => 'W789',
        'price' => 39.99,
        'image_path' => 'storage/products/watch.jpg',
    ],
];
?>

2. Create shopping cart web route URLs

In this Laravel add-to-cart example, the following web URL rules are created to perform the shopping cart operations. The supported cart operations are add-to-cart, delete item or clear cart, bulk-add-to-cart and filtering product.

routes/web.php

<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\ProductController;
use App\Http\Controllers\CartController;

Route::get('/', [ProductController::class, 'index'])->name('products.index');
Route::get('/products/{product_code}', [ProductController::class, 'viewProduct'])->name('products.view');
Route::post('/add-to-cart', [ProductController::class, 'addToCart']);
Route::post('/bulk-add-to-cart', [ProductController::class, 'bulkAddToCart']);

Route::get('/cart', [CartController::class, 'cart'])->name('cart');
Route::get('clear-cart', [CartController::class, 'clearCart']);
Route::post('/remove-from-cart', [CartController::class, 'deleteProduct'])->name('delete.cart.product');

Route::get('/search', [ProductController::class, 'productSearch'])->name('products.search');
?>

3. Design Laravel templates with add-to-cart options

There are three templates created for the Laravel add-to-cart project.

  1. Product Gallery
  2. Product view page
  3. Search result template

These three templates have the products with an add-to-cart option. The search result list allows one to select multiple products to push bulk data to the Laravel shopping cart.

Add-to-cart from the product gallery

resources/views/products.blade.php

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title>Add to Cart in Laravel</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.2/css/bootstrap.min.css">
    <style>
        body{
        padding: 2rem 0rem;
        }
        .image-parent {
        max-width: 60px;
        border: #F0F0F0 1px solid;
        }
    </style>
</head>

<body>
    <div class="container">
        @include('header')
        <div class="row mt-5">
            @foreach ($products as $index => $product)
            <div class="col-md-4 mb-4">
                <div class="card" style="width:23rem">
                    <a href="{{ route('products.view', ['product_code' => $product['code']]) }}"><img src="{{ asset($product['image_path']) }}" class="card-img-top" alt="{{ $product['name'] }}"></a>
                    <div class="card-body">
                        <h5 class="card-title">{{ $product['name'] }}</h5>
                        <p class="card-text">Code# {{ $product['code'] }}</p>
                        <p class="card-text">${{ $product['price'] }}</p>
                        <span class="">
                            <span class="btn btn-primary add-text add-to-cart" data-product-code="{{ $product['code'] }}">Add to cart</span> <span class="btn btn-primary d-none adding-text">Adding</span>
                            <span class="btn btn-primary d-none added-text">Added. <a href="/cart" class="text-white text-decoration-none">Go to cart</a></span></span>
                    </div>
                </div>
            </div>
            @endforeach
        </div>

    </div>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</body>

</html>

Add-to-cart from the product view template

resources/views/view.blade.php

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title>Product view</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
    <style>
        img {
            max-width: 100%;
            height: auto;
        }
    </style>
</head>

<body>
    <div class="container">
        @include('header')
        @if($productDetails)

        <div class="mt-5 d-flex w-100">
            <div class="w-50"><img src="{{ asset($productDetails['image_path']) }}"></div>
            <div class="ms-5 w-75">
                <h2>{{ $productDetails['name'] }}</h2>
                <h4>${{ $productDetails['price'] }}</h4>
                <div>Code# {{ $productDetails['code'] }}</div>
                <span class="btn btn-primary mt-3">
                    <span class="add-text add-to-cart" data-product-code="{{ $productDetails['code'] }}">Add to cart</span> <span class="d-none adding-text">Adding</span>
                    <span class="d-none added-text">Added. <a href="/cart" class="text-white text-decoration-none">Go to cart</a></span></span>
            </div>
        </div>
        @endif
    </div>

</body>

</html>

Bulk add-to-cart from a product filter in the header

The Laravel shopping cart application header consists of a product filter. The below code is to include a header into the Laravel page templates.

On entering text into this filter, it will show a product list in a suggestion box.

resources/views/header.blade.php

<nav class="navbar navbar-light bg-light">
    <div class="container-fluid">
        <h3><a href="/" class="text-decoration-none text-dark">Laravel Cart</a></h3>
        <div class="d-flex w-50">
            <div class="position-relative" style="width:80%">
                <div>
                    <input class="form-control me-2" id="product-search" type="text" autocomplete="off" placeholder="Enter product code, e.g. H123,C456">
                </div>
                <div id="product-details-container" class="position-absolute top-100 start-0 bg-light z-2 w-100"></div>
            </div>
            <button class="btn btn-outline-success bulk-upload mx-2" type="button">Add to cart</button>
        </div>

        <a href="/cart" class="text-decoration-none"><img class="mx-2" src="{{ asset('images/shopping-cart.svg') }}">View Cart</a>
    </div>
</nav>

The below HTML is to display the list of products on changing the filter input. When selecting an item from the suggested result, it will add the code to the input.

If multiple products are selected, it adds a comma-separated product code to the filter. It helps to perform a bulk add-to-cart action.

resources/views/search_results.blade.php

@if (!empty($searchResults))

        <ul class="list-group">
        @foreach ($searchResults as $product)
        <a class="list-group-item list-group-item-action d-flex justify-content-between align-items-center product" data-code="{{ $product['code'] }}" style="cursor: pointer;">
          <div class="flex-column">
          {{ $product['name'] }}
            <p><small>${{ $product['price'] }}</small></p>
          </div>
          <div class="image-parent">
              <img src="{{ asset($product['image_path']) }}" class="img-fluid">
          </div>
        </a>
        @endforeach
      </ul>

@else
<p class="mx-3 mt-3">No products found.</p>
@endif

laravel cart product suggestion

4. Register event handlers to perform product search and cart actions

There are many JavaScript event handlers registered for this Laravel add-to-cart application. Those are for the following purposes.

  • On clicking the “add-to-cart”, the selected product is added to the cart.
  • On changing the product filter, show a suggestion list.
  • On selecting a product from the suggestions, append the code for a bulk-add-to-cart.
  • On clicking delete or clear cart, remove single or entire cart items respectively.

Adding product to shopping cart

The below code is part of the product gallery and product-view templates to perform add-to-cart and product searches. The product search and the bulk add-to-cart is enabled on the common header template.

$('.add-to-cart').click(function() {
    var addButton = $(this);
    var productCode = addButton.data('product-code');
    addButton.closest('div').find('.add-text').hide();
    addButton.closest('div').find('.adding-text').removeClass('d-none');
    $.ajax({
        type: 'POST',
        url: '/add-to-cart',
        data: {
            product_code: productCode,
            _token: '{{ csrf_token() }}'
        },
        success: function(response) {
            addButton.closest('div').find('.adding-text').addClass('d-none');
            addButton.closest('div').find('.added-text').removeClass('d-none');
        }
    });
});

$('.bulk-add-to-cart').click(function() {
    var productCodes = $('#product-search').val();
    $.ajax({
        type: 'POST',
        url: '/bulk-add-to-cart',
        data: {
            product_code: productCodes,
            _token: '{{ csrf_token() }}'
        },
        success: function(response) {
            window.location.href = '/cart';
        },
        error: function(xhr, status, error) {
            alert('Error: ' + xhr.responseText);
        }
    });

});

$('#product-search').keyup(function() {
    var productCode = $(this).val();
    if (productCode.includes(',')) {

        var productCodes = productCode.split(',');
    }
    $.ajax({
        type: 'GET',
        url: '/search', 
        data: {
            product_code: productCode
        },
        success: function(response) {
            $('#product-details-container').html(response);
            $('#product-details-container').show();
        }
    });
});

Filtering product result by entering keyword

When clicking a product list item from the filtered result, the below event handler will be called.

It pushes the selected product code to the search input. The search box contains a button which pushes the selected product data into a cart session in one click.

$(document).ready(function() {
    var productCodes = [];

    // On clicking the search result item, append the code to the filter input
    $('.product').click(function() {
        var productCode = $(this).data('code');

        if (!productCodes.includes(productCode)) {
            productCodes.push(productCode);
        }

        $('#product-search').val(productCodes.join(','));
    });
});

Cart ‘delete’ and ‘clear’ actions

The cart deletes and clear actions are the common functionalities of an eCommerce application.

Each cart item has a “remove” button. The below code shows how to register the delete button’s click event to call the cart item delete action.

On clicking the “clear cart” button, it wipes out the entire cart by using a single line of code.

The delete action prompts user confirmation via JavaScript before request deleting.

$(".delete-item").click(function() {
    var removeButton = $(this); 
    var productCode = removeButton.data('product-code');
    if (confirm("Are you sure you want to remove product from the cart?")) {
        removeButton.closest('div').find('.remove-text').hide();
        removeButton.closest('div').find('.removing-text').removeClass('d-none');
        $.ajax({
            type: 'POST',
            url: '{{ url("remove-from-cart") }}',
            data: {
                _token: '{{ csrf_token() }}',
                product_code: productCode
            },
            success: function(response) {
                removeButton.closest('div').find('.removing-text').addClass('d-none'); 
                removeButton.closest('div').find('.removed-text').removeClass('d-none'); 
                window.location.reload();
            }
        });
    }
});

$('#clear-cart-btn').click(function(e) {
    e.preventDefault();

    if (confirm('Are you sure you want to clear your cart?')) {
        window.location.href = $(this).attr('href');
    } else {
        return false;
    }
});

5. Manage cart items in session via app controllers

This section shows a cart controller class. It shows how the cart list, add, delete and clear action handles are coded.

The cart delete handler receives the particular product code via the AJAX POST request.

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Redirect;

class CartController extends Controller
{
    public function cart()
    {
        return view('cart');
    }

    public function clearCart()
    {
        session()->forget('cart');
        return redirect()->back();
    }

    public function deleteProduct(Request $request)
    {
        if ($request->product_code) {
            $cart = session()->get('cart');
            if (isset($cart[$request->product_code])) {
                unset($cart[$request->product_code]);
                session()->put('cart', $cart);
            }
        }
    }
}
?>

The below template contains an HTML table that displays rows of cart items from the session.

The cart table displays minimal data on the products in the cart. It shows the product name, price, and quantity with the image thumbnails.

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title>Laravel</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
</head>

<body>
    <div class="container">
        @include('header')
        @if(session('success'))
        <div class="alert alert-success">
            {{ session('success') }}
        </div>
        @endif
        <a href="{{ url('clear-cart') }}" id="clear-cart-btn"><button class="btn btn-danger mb-2 float-end">Clear Cart</button></a>
        <table id="cart" class="table table-bordered">
            <thead>
                <tr>
                    <th>Product</th>
                    <th class="text-center">Quantity</th>
                    <th class="text-end">Price</th>
                    <th class="text-end">Total</th>
                    <th class="text-center">Action</th>
                </tr>
            </thead>
            <tbody>
                @if(session('cart'))

                @foreach(session('cart') as $id => $details)

                <tr rowId="{{ $id }}">
                    <td data-th="Product">
                        <div class="row">
                            <div class="col-sm-3 hidden-xs"><a href="{{ route('products.view', ['product_code' => $details['code']]) }}"><img src="{{ asset($details['image']) }}" width="100" height="80" class="img-responsive" /></a>
                            </div>
                            <div class="col-sm-9">
                                <h5 class="my-auto">{{ $details['name'] }}</h5>
                            </div>
                        </div>
                    </td>
                    <td class="text-center">{{ $details['quantity'] }}</td>
                    <td class="text-end">${{ $details['price'] }}</td>
                    <td class="text-end">${{ $details['quantity'] * $details['price'] }}</td>
                    <td class="text-center">
                        <span>
                            <span class="btn btn-outline-danger remove-text delete-item" data-product-code="{{ $details['code'] }}">Remove Item</span>
                            <span class="btn btn-outline-danger d-none removing-text">Removing</span>
                            <span class="btn btn-outline-danger d-none removed-text">Removed.</span></span>
                    </td>
                </tr>
                @endforeach
                @endif
            </tbody>

        </table>
    </div>
</body>

</html>

Thus we have created an add-to-cart option from multiple points in Laravel. If you are new to Laravel, setting up the development environment is required.
view demo Download

Vincy
Written by Vincy, a web developer with 15+ years of experience and a Masters degree in Computer Science. She specializes in building modern, lightweight websites using PHP, JavaScript, React, and related technologies. Phppot helps you in mastering web development through over a decade of publishing quality tutorials.

Leave a Reply

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

↑ Back to Top

Share this page