laravel 9 add wishlist tutorial example

In this section we will see how to add wishlist system in laravel 9. For this tutorial we will use Laravel Markable. The Laravel Markable package allows you to manage your wishlists. It also allows users to create and edit their own wishlists. We need to create a product and add the wishlist.


Step 1: Install Laravel & Connect Database

Run below command to create laravel project.

composer create-project laravel/laravel laravel-wishlist

Now, you have to connect the laravel app to the database, hence open the .env configuration file and add the database credentials as suggested below.

.env

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=database_name
DB_USERNAME=database_user_name
DB_PASSWORD=database_password


Step 2: Install Breeze

Install laravel breeze via composer:

composer require laravel/breeze --dev

Next, run below command.

php artisan breeze:install

And final install Dependencies

npm install && npm run dev 
php artisan migrate


Step 3: Create Product Modal Migration Seeder and Controller

Run below command to create model, migration and controller

php artisan make:model Product -mcr


create_products_table.php

public function up()
{
    Schema::create('products', function (Blueprint $table) {
        $table->id();
        $table->string('name');
        $table->double('price');
        $table->text('description');
        $table->string('image');
        $table->timestamps();
    });
}


app/Models/Product.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
    use HasFactory;

    protected $fillable = [
        'name',
        'price',
        'image',
        'description',
    ];
}


Step 4: Create Product Seeder

php artisan make:seeder ProductSeeder

Now add dummy data in seeder.

database/seeders/ProductSeeder.php

<?php

namespace Database\Seeders;

use App\Models\Product;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;

class ProductSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        $products = [
            [
                'name' => 'Fesh milk 250ml',
                'price' => 250,
                'description' => 'lorem ipsum',
                'image' => 'https://cdn.pixabay.com/photo/2016/12/06/18/27/milk-1887234__340.jpg'
            ],
            [
                'name' => '12 Egs',
                'price' => 6,
                'description' => 'lorem ipsum',
                'image' => 'https://cdn.pixabay.com/photo/2016/07/23/15/24/egg-1536990__340.jpg'
            ],
            [
                'name' => 'Wine 500ml',
                'price' => 50,
                'description' => 'lorem ipsum',
                'image' => 'https://cdn.pixabay.com/photo/2015/11/07/12/00/alcohol-1031713__340.png'
            ],
            [
                'name' => 'Homey 100ml',
                'price' => 12,
                'description' => 'lorem ipsum',
                'image' => 'https://cdn.pixabay.com/photo/2017/01/06/17/49/honey-1958464__340.jpg'
            ]
        ];
        Product::insert($products);
    }
}


database/seeders/DatabaseSeeder.php

<?php

namespace Database\Seeders;

// use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     *
     * @return void
     */
    public function run()
    {
        $this->call(ProductSeeder::class);

        // \App\Models\User::factory(10)->create();

        // \App\Models\User::factory()->create([
        //     'name' => 'Test User',
        //     'email' => '[email protected]',
        // ]);
    }
}


app/Http/Controllers/ProductController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Product;


class ProductController extends Controller
{
    public function productList()
    {
        $products = Product::all();

        return view('products', compact('products'));
    }
}


Step 5: Install & Setup Laravel Markable For Wishlist

You can install the package via composer:

composer require maize-tech/laravel-markable


publishes favorite migration.

php artisan vendor:publish --tag="markable-migration-favorite"


You can publish the config file with:

php artisan vendor:publish --tag="markable-config"


Migrate table with seeder.

php artisan migrate:fresh --seed


Step 6: Add Markable Favorite in Product Modal

app/Models/Product.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Maize\Markable\Markable;
use Maize\Markable\Models\Favorite;

class Product extends Model
{
    use HasFactory, Markable;

    protected $fillable = [
        'name',
        'price',
        'image',
        'description',
    ];

    protected static $marks = [
        Favorite::class,
    ];
}


Step 7: Create Wishlist Controller and Routes

Copy the following code below to create a wishlist controller.

php artisan make:controller WishlistController


Add a favoriteAdd and favoriteRemove method to the Wishlist class to add items to the wishlist. This method should be called after an item has been added to the list, but before it's added to the shopping cart. If a product is added and then removed, this method should remove it from the list.

app/Http/Controllers/WishlistController.php

<?php

namespace App\Http\Controllers;

use App\Models\Product;
use Maize\Markable\Models\Favorite;
use Illuminate\Http\Request;

class WishlistController extends Controller
{
    public function wishlist()
    {
        $products = Product::whereHasFavorite(
            auth()->user()
        )->get(); 
        // dd($products);
        return view('wishlist',compact('products'));
    }

    public function favoriteAdd($id)
    {
        $product = Product::find($id);
        $user = auth()->user();
        Favorite::add($product, $user);
        session()->flash('success', 'Product is Added to Favorite Successfully !');

        return redirect()->route('wishlist');
    }

    public function favoriteRemove($id)
    {
        $product = Product::find($id);
        $user = auth()->user();
        Favorite::remove($product, $user);
        session()->flash('success', 'Product is Remove to Favorite Successfully !');

        return redirect()->route('wishlist');
    }
}


web.php

<?php

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

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', function () {
    return view('welcome');
});


Route::get('products', [ProductController::class, 'productList'])->name('products.list');
Route::post('favorite-add/{id}', [WishlistController::class, 'favoriteAdd'])->name('favorite.add');
Route::delete('favorite-remove/{id}', [WishlistController::class, 'favoriteRemove'])->name('favorite.remove');


Route::get('wishlist', [WishlistController::class, 'wishlist'])->name('wishlist');

Route::get('/dashboard', function () {
    return view('dashboard');
})->middleware(['auth'])->name('dashboard');

require __DIR__.'/auth.php';


Step 8: Add Wishlist in Laravel Blade View Files

resources/views/products.blade.php

<x-app-layout>
    <x-slot name="header">
        <h2 class="text-xl font-semibold leading-tight text-gray-800">
            {{ __('Product List') }}
        </h2>
    </x-slot>
    <div class="container px-12 py-8 mx-auto">
        <h3 class="text-2xl font-bold text-purple-700">Our Product</h3>
        <div class="h-1 bg-red-500 w-36"></div>
        <div class="grid grid-cols-1 gap-6 mt-6 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
            @foreach ($products as $product)
            <div class="w-full max-w-sm mx-auto overflow-hidden bg-white rounded-md shadow-md">
                <img src="{{ url($product->image) }}" alt="" class="w-full max-h-60">
                <div class="flex items-end justify-end w-full bg-cover">

                </div>
                <div class="px-5 py-3">
                    <h3 class="text-gray-700 uppercase">{{ $product->name }}</h3>
                    <span class="mt-2 text-gray-500">${{ $product->price }}</span>
                    <form action="{{ route('favorite.add', $product->id) }}" method="POST"
                        enctype="multipart/form-data">
                        @csrf
                        <button class="p-2 bg-red-100 rounded hover:bg-red-600">
                            <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5"
                                stroke="currentColor" class="w-6 h-6 text-red-700 hover:text-red-100">
                                <path stroke-linecap="round" stroke-linejoin="round"
                                    d="M21 8.25c0-2.485-2.099-4.5-4.688-4.5-1.935 0-3.597 1.126-4.312 2.733-.715-1.607-2.377-2.733-4.313-2.733C5.1 3.75 3 5.765 3 8.25c0 7.22 9 12 9 12s9-4.78 9-12z" />
                            </svg>

                        </button>
                    </form>
                </div>

            </div>
            @endforeach
        </div>
    </div>
</x-app-layout>
laravel 9 product with wishlist icon

laravel 9 product with wishlist icon


resources/views/wishlist.blade.php

<x-app-layout>
    <x-slot name="header">
        <h2 class="text-xl font-semibold leading-tight text-gray-800">
            {{ __('wishlist') }}
        </h2>
    </x-slot>

    <div class="py-12">
        <div class="mx-auto max-w-7xl sm:px-6 lg:px-8">
            <div class="overflow-hidden bg-white shadow-sm sm:rounded-lg">
                <div class="p-6 bg-white border-b border-gray-200">
                    Wishlist List
                    @if ($message = Session::get('success'))
                          <div class="p-4 mb-3 bg-green-400 rounded">
                              <p class="text-green-800">{{ $message }}</p>
                          </div>
                      @endif
                    <div class="flex flex-col">
                        <div class="overflow-x-auto">
                            <div class="p-1.5 w-full inline-block align-middle">
                                <div class="overflow-hidden border rounded-lg">
                                    <table class="min-w-full divide-y divide-gray-200">
                                        <thead class="bg-gray-50">
                                            <tr>
                                                <th
                                                    scope="col"
                                                    class="px-6 py-3 text-xs font-bold text-left text-gray-500 uppercase"
                                                >
                                                    ID
                                                </th>
                                                <th
                                                    scope="col"
                                                    class="px-6 py-3 text-xs font-bold text-left text-gray-500 uppercase"
                                                >
                                                   Product Name
                                                </th>
                                                <th
                                                    scope="col"
                                                    class="px-6 py-3 text-xs font-bold text-left text-gray-500 uppercase"
                                                >
                                                    Price
                                                </th>
                                                <th
                                                    scope="col"
                                                    class="px-6 py-3 text-xs font-bold text-left text-gray-500 uppercase"
                                                >
                                                    Image
                                                </th>
                                                <th
                                                    scope="col"
                                                    class="px-6 py-3 text-xs font-bold text-right text-gray-500 uppercase"
                                                >
                                                    Delete
                                                </th>
                                            </tr>
                                        </thead>
                                        <tbody class="divide-y divide-gray-200">
                                            @foreach ($products as $product)
                                                
                                            
                                            <tr>
                                                <td
                                                    class="px-6 py-4 text-sm font-medium text-gray-800 whitespace-nowrap"
                                                >
                                                    {{ $product->id }}
                                                </td>
                                                <td
                                                    class="px-6 py-4 text-sm text-gray-800 whitespace-nowrap"
                                                >
                                                {{ $product->name }}
                                                   
                                                </td>
                                                <td
                                                    class="px-6 py-4 text-sm text-gray-800 whitespace-nowrap"
                                                >
                                                {{ $product->price }}
                                                    
                                                </td>
                                                <td
                                                    class="px-6 py-4 text-sm text-gray-800 whitespace-nowrap"
                                                >
                                              <img src="{{ $product->image }}" alt="{{ $product->image }}" class="w-12 h-12">  
                                                    
                                                </td>
                                               
                                                <td
                                                    class="px-6 py-4 text-sm font-medium text-right whitespace-nowrap"
                                                >
                                                <form action="{{ route('favorite.remove',$product->id) }}" method="POST"
                                                    onsubmit="return confirm('{{ trans('are You Sure ? ') }}');"
                                                    style="display: inline-block;">
                                                    <input type="hidden" name="_method" value="DELETE">
                                                    <input type="hidden" name="_token" value="{{ csrf_token() }}">
                                                    <input type="submit" class="px-4 py-2 text-white bg-red-700 rounded"
                                                        value="Delete">
                                                </form>
                                                </td>
                                            </tr>
                                            @endforeach
                                        </tbody>
                                    </table>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>

                
            </div>
        </div>
    </div>
</x-app-layout>
laravel 9 add and remove wishlist

laravel 9 add and remove wishlist


Step 9: Run Laravel and vite server

php artisan serve
//and next terminal
npm run dev