Laravel E-Commerce Application Development – Product Details Page
Laravel E-Commerce Application Development ( 27 Lessons )
In this course, you’ll learn how to create an E-Commerce Website from scratch in Laravel. The process has never been easier I’ll take you from the very beginning stages of setting up Laravel till the last steps of adding products to the cart. If you’ve good understanding & experience in PHP & MySQL then this course is for you.
see full series- Laravel E-Commerce Application Development – Introduction
- Laravel E-Commerce Application Development – Initial Project Setup
- Laravel E-Commerce Application Development – Assets Setup Using Laravel Mix
- Laravel E-Commerce Application Development – Admin Model and Migration
- Laravel E-Commerce Application Development – Backend Admin Authentication
- Laravel E-Commerce Application Development – Base Controller and Repository
- Laravel E-Commerce Application Development – Settings Section Part 1
- Laravel E-Commerce Application Development – Settings Section Part 2
- Laravel E-Commerce Application Development – Categories Section Part 1
- Laravel E-Commerce Application Development – Categories Section Part 2
- Laravel E-Commerce Application Development – Attributes Section Part 1
- Laravel E-Commerce Application Development – Attributes Section Part 2
- Laravel E-Commerce Application Development – Attributes Section Part 3
- Laravel E-Commerce Application Development – Brands Section
- Laravel E-Commerce Application Development – Products Section Part 1
- Laravel E-Commerce Application Development – Products Section Part 2
- Laravel E-Commerce Application Development – Products Section Part 3
- Laravel E-Commerce Application Development – Products Section Part 4
- Laravel E-Commerce Application Development – Frontend Login & Registration
- Laravel E-Commerce Application Development – Categories Navigation
- Laravel E-Commerce Application Development – Catalog Listing
- Laravel E-Commerce Application Development – Product Details Page
- Laravel E-Commerce Application Development – Shopping Cart
- Laravel E-Commerce Application Development – Checkout
- Laravel E-Commerce Application Development – Payment Processing
- Laravel E-Commerce Application Development – Order Management
- Laravel E-Commerce Application Development – Wrap Up
This is part 21 of the Laravel E-Commerce Application Development series. In this part, we will start implementing the product details page.
I assume you should have the e-commerce application project on your machine or you can grab it from Laravel E-Commerce Application repository, we will start from where we left it in the last part.
Updating Product Controller show Method
In the previous post, we created a show()
method in our Product Controller. Instead of dumping the current product, we will return a new view file which will show the product details. As on our product page, we would like to show the product attributes as well, so will load all attributes and supply to this our new view.
Within our Product Controller, add the below statement before the class declaration.
use App\Contracts\AttributeContract;
Next, we will add a new protected property to include the attribute repository.
protected $attributeRepository;
Next, we will inject the App\Contracts\AttributeContract class to our constructor.
public function __construct(ProductContract $productRepository, AttributeContract $attributeRepository) { $this->productRepository = $productRepository; $this->attributeRepository = $attributeRepository; }
Now, we will update the show()
method which will return the product details view.
public function show($slug) { $product = $this->productRepository->findProductBySlug($slug); $attributes = $this->attributeRepository->listAttributes(); return view('site.pages.product', compact('product', 'attributes')); }
Adding the Add To Cart Route
Before proceeding to the product details page, I would like to create a new POST
route for our add to cart functionality. Open the routes/web.php
file and add the below route in it.
Route::post('/product/add/cart', 'Site\ProductController@addToCart')->name('product.add.cart');
Adding addToCart() Method in Product Controller
Now, our add to cart route is pointing to addToCart()
method, so we will add that in our Product Controller.
public function addToCart(Request $request) { dd($request->all()); }
That’s it for now, let’s move on to the product details page for our application.
Creating Product Details Page
To explain the product details page, I will share the code snippets with the explanation. At the end of this post, I will share the full file for product details.
Head over to resources/views/site/pages
folder and add a new file name product.blade.php
.
Open this file and add the below HTML markup in it.
@extends('site.app') @section('title', $product->name) @section('content') <section class="section-pagetop bg-dark"> <div class="container clearfix"> <h2 class="title-page">{{ $product->name }}</h2> </div> </section> <section class="section-content bg padding-y border-top" id="site"> <div class="container"> <div class="row"> {{--All Content will goes here--}} </div> </div> </section> @stop
In this HTML markup, we have simply extended the main layout and added a header section which will show the product name. Next, we have a section container, which will holde the whole product page.
Now, add below markup within the row div in the above code snippet.
<div class="col-md-12"> <div class="card"> <div class="row no-gutters"> </div> </div> </div>
In the above row no-gutters div, we will create an aside section with 5 columns. Add the below markup in it.
<aside class="col-sm-5 border-right"> <article class="gallery-wrap"> @if ($product->images->count() > 0) <div class="img-big-wrap"> <div class="padding-y"> <a href="{{ asset('storage/'.$product->images->first()->full) }}" data-fancybox=""> <img src="{{ asset('storage/'.$product->images->first()->full) }}" alt=""> </a> </div> </div> @else <div class="img-big-wrap"> <div> <a href="https://via.placeholder.com/176" data-fancybox=""><img src="https://via.placeholder.com/176"></a> </div> </div> @endif @if ($product->images->count() > 0) <div class="img-small-wrap"> @foreach($product->images as $image) <div class="item-gallery"> <img src="{{ asset('storage/'.$image->full) }}" alt=""> </div> @endforeach </div> @endif </article> </aside>
In the above code snippet, firstly we are checking if any images exist for the current product. If yes then we will show the first image for the current product. If not, we will show a placeholder image.
Next, again checking if there are any images we will run a loop on the images and show each image as a thumbnail.
Now, we will add a new aside section just after the previous aside section.
<aside class="col-sm-7"> <article class="p-5"> <h3 class="title mb-3">{{ $product->name }}</h3> <dl class="row"> <dt class="col-sm-3">SKU</dt> <dd class="col-sm-9">{{ $product->sku }}</dd> <dt class="col-sm-3">Weight</dt> <dd class="col-sm-9">{{ $product->weight }}</dd> </dl> <div class="mb-3"> @if ($product->sale_price > 0) <var class="price h3 text-danger"> <span class="currency">{{ config('settings.currency_symbol') }}</span><span class="num" id="productPrice">{{ $product->sale_price }}</span> <del class="price-old"> {{ config('settings.currency_symbol') }}{{ $product->price }}</del> </var> @else <var class="price h3 text-success"> <span class="currency">{{ config('settings.currency_symbol') }}</span><span class="num" id="productPrice">{{ $product->price }}</span> </var> @endif </div> <hr> <form action="{{ route('product.add.cart') }}" method="POST" role="form" id="addToCart"> @csrf <div class="row"> <div class="col-sm-12"> <dl class="dlist-inline"> @foreach($attributes as $attribute) @php $attributeCheck = in_array($attribute->id, $product->attributes->pluck('attribute_id')->toArray()) @endphp @if ($attributeCheck) <dt>{{ $attribute->name }}: </dt> <dd> <select class="form-control form-control-sm option" style="width:180px;" name="{{ strtolower($attribute->name ) }}"> <option data-price="0" value="0"> Select a {{ $attribute->name }}</option> @foreach($product->attributes as $attributeValue) @if ($attributeValue->attribute_id == $attribute->id) <option data-price="{{ $attributeValue->price }}" value="{{ $attributeValue->value }}"> {{ ucwords($attributeValue->value . ' +'. $attributeValue->price) }} </option> @endif @endforeach </select> </dd> @endif @endforeach </dl> </div> </div> <hr> <div class="row"> <div class="col-sm-12"> <dl class="dlist-inline"> <dt>Quantity: </dt> <dd> <input class="form-control" type="number" min="1" value="1" max="{{ $product->quantity }}" name="qty" style="width:70px;"> <input type="hidden" name="productId" value="{{ $product->id }}"> <input type="hidden" name="price" id="finalPrice" value="{{ $product->sale_price != '' ? $product->sale_price : $product->price }}"> </dd> </dl> </div> </div> <hr> <button type="submit" class="btn btn-success"><i class="fas fa-shopping-cart"></i> Add To Cart</button> </form> </article> </aside>
There is a lot of things going on int this aside section. We start by showing the product name, SKU and weight. Then moving on to showing the product price, if there is a sale price we will show that.
Next, we have a form which is pointing to the add to cart route. Within this form, firstly we are firstly looping through all attributes which we loaded in the Product Controller.
Within, this loop firstly we will make a check if the current attribute in the loop iteration is same as the product attribute (I used the pluck()
method to get the product attributes ids and then checked it with the current attribute id.), if yes then we will show the product attribute.
Next, we will iterate through the product attribute values. Within the select box’s option, I am setting the data-price element which we will use in the JavaScript to change the price based on attribute selected.
Next, we are showing the quantity box and also I have added the two productId
and price
hidden fields which we will submit in this form.
Finally, we have we submit button.
Now, we will create a new 12 column section and display the product description like below.
<div class="col-md-12"> <article class="card mt-4"> <div class="card-body"> {!! $product->description !!} </div> </article> </div>
There is some javascript which I added to change the price of the product based on the attribute selected.
Right at the bootom of this file after @stop add the below code snippet.
@push('scripts') <script> $(document).ready(function () { $('#addToCart').submit(function (e) { if ($('.option').val() == 0) { e.preventDefault(); alert('Please select an option'); } }); $('.option').change(function () { $('#productPrice').html("{{ $product->sale_price != '' ? $product->sale_price : $product->price }}"); let extraPrice = $(this).find(':selected').data('price'); let price = parseFloat($('#productPrice').html()); let finalPrice = (Number(extraPrice) + price).toFixed(2); $('#finalPrice').val(finalPrice); $('#productPrice').html(finalPrice); }); }); </script> @endpush
Open the resources/views/site/partials/scripts.blade.php file and add the below stack directive at the end of the file.
@stack('scripts')
product.blade.php File
@extends('site.app') @section('title', $product->name) @section('content') <section class="section-pagetop bg-dark"> <div class="container clearfix"> <h2 class="title-page">{{ $product->name }}</h2> </div> </section> <section class="section-content bg padding-y border-top" id="site"> <div class="container"> <div class="row"> <div class="col-md-12"> <div class="card"> <div class="row no-gutters"> <aside class="col-sm-5 border-right"> <article class="gallery-wrap"> @if ($product->images->count() > 0) <div class="img-big-wrap"> <div class="padding-y"> <a href="{{ asset('storage/'.$product->images->first()->full) }}" data-fancybox=""> <img src="{{ asset('storage/'.$product->images->first()->full) }}" alt=""> </a> </div> </div> @else <div class="img-big-wrap"> <div> <a href="https://via.placeholder.com/176" data-fancybox=""><img src="https://via.placeholder.com/176"></a> </div> </div> @endif @if ($product->images->count() > 0) <div class="img-small-wrap"> @foreach($product->images as $image) <div class="item-gallery"> <img src="{{ asset('storage/'.$image->full) }}" alt=""> </div> @endforeach </div> @endif </article> </aside> <aside class="col-sm-7"> <article class="p-5"> <h3 class="title mb-3">{{ $product->name }}</h3> <dl class="row"> <dt class="col-sm-3">SKU</dt> <dd class="col-sm-9">{{ $product->sku }}</dd> <dt class="col-sm-3">Weight</dt> <dd class="col-sm-9">{{ $product->weight }}</dd> </dl> <div class="mb-3"> @if ($product->sale_price > 0) <var class="price h3 text-danger"> <span class="currency">{{ config('settings.currency_symbol') }}</span><span class="num" id="productPrice">{{ $product->sale_price }}</span> <del class="price-old"> {{ config('settings.currency_symbol') }}{{ $product->price }}</del> </var> @else <var class="price h3 text-success"> <span class="currency">{{ config('settings.currency_symbol') }}</span><span class="num" id="productPrice">{{ $product->price }}</span> </var> @endif </div> <hr> <form action="{{ route('product.add.cart') }}" method="POST" role="form" id="addToCart"> @csrf <div class="row"> <div class="col-sm-12"> <dl class="dlist-inline"> @foreach($attributes as $attribute) @php $attributeCheck = in_array($attribute->id, $product->attributes->pluck('attribute_id')->toArray()) @endphp @if ($attributeCheck) <dt>{{ $attribute->name }}: </dt> <dd> <select class="form-control form-control-sm option" style="width:180px;" name="{{ strtolower($attribute->name ) }}"> <option data-price="0" value="0"> Select a {{ $attribute->name }}</option> @foreach($product->attributes as $attributeValue) @if ($attributeValue->attribute_id == $attribute->id) <option data-price="{{ $attributeValue->price }}" value="{{ $attributeValue->value }}"> {{ ucwords($attributeValue->value . ' +'. $attributeValue->price) }} </option> @endif @endforeach </select> </dd> @endif @endforeach </dl> </div> </div> <hr> <div class="row"> <div class="col-sm-12"> <dl class="dlist-inline"> <dt>Quantity: </dt> <dd> <input class="form-control" type="number" min="1" value="1" max="{{ $product->quantity }}" name="qty" style="width:70px;"> <input type="hidden" name="productId" value="{{ $product->id }}"> <input type="hidden" name="price" id="finalPrice" value="{{ $product->sale_price != '' ? $product->sale_price : $product->price }}"> </dd> </dl> </div> </div> <hr> <button type="submit" class="btn btn-success"><i class="fas fa-shopping-cart"></i> Add To Cart</button> </form> </article> </aside> </div> </div> </div> <div class="col-md-12"> <article class="card mt-4"> <div class="card-body"> {!! $product->description !!} </div> </article> </div> </div> </div> </section> @stop @push('scripts') <script> $(document).ready(function () { $('#addToCart').submit(function (e) { if ($('.option').val() == 0) { e.preventDefault(); alert('Please select an option'); } }); $('.option').change(function () { $('#productPrice').html("{{ $product->sale_price != '' ? $product->sale_price : $product->price }}"); let extraPrice = $(this).find(':selected').data('price'); let price = parseFloat($('#productPrice').html()); let finalPrice = (Number(extraPrice) + price).toFixed(2); $('#finalPrice').val(finalPrice); $('#productPrice').html(finalPrice); }); }); </script> @endpush
Now, if you open a product you will have product page something like below.

What’s Next
In the next post, we will start working on the shopping cart and create a cart page for our this application.
Code Repository
You can find the code base of this series on Laravel eCommerce Application repository.
If you have any question about this post, please leave a comment in the comment box below.