How to create and use Reusable Modal using Alpine.js

How to create and use Reusable Modal using Alpine.js

In this blog, we are creating a reusable modal in laravel 8 and livewire using Alpine.js. Basically Modal is used to work on another page without redirecting to another page.

Alpine.js is a rugged, simple, and minimal framework for composing JavaScript behavior in your front-end web applications. It allows us to write JS inline in our HTML. It is developed by Caleb Porzio who aims to fill the void between jQuery and large frameworks like Vue/React. It is very easy to install we only need to add a script tag for linking.

Let' start by creating a project and we will see how to use it and make a reusable modal.

Steps to follow -

  1. Create Laravel project and Install Livewire
  2. Add alpine.js script in the head tag
  3. Add livewire blade directives
  4. Create Modal Livewire Component
  5. Usage of Modal

Step 1 - First we will create and install laravel and livewire using composer

composer create-project --prefer-dist laravel/laravel reusable-modal-ex

Now install Livewire

composer require livewire/livewire

Step 2 - Add alpine.js script in the head tag

  <head>
    ...
    <script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.8.2/dist/alpine.min.js" defer></script>
    ...
  </head>

Step 3 - Add Livewire blade directive to head and before end of the body tag

<html>
<head>
   ...
   @livewireStyles
 </head>
 <body>
    ...
    @livewireScripts
 </body>
 </html>

After we have to publish the config and front-end assets using the following command

php artisan livewire:publish --config
php artisan livewire:publish --assets

We arrived to the exciting part :blush: of creating re-usable modal

Step 4 - In this step we will create a Livewire component

php artisan make:livewire Modal

It will create two files as shown below -

CLASS: app/Http/Livewire//Modal.php
VIEW:  C:\xampp\htdocs\reusable-modal-ex\resources\views/livewire/modal.blade.php

Delete the view file modal.blade.php we don't require it.

Let's start the magic with the help of alpine.js :smiley:

Go to App\Http\Livewire\Modal.php and add code within Modal Component and delete render method, because we are not returning any view from this Controller.

public $show = false;

protected $listeners = [
  'show' => 'show'
];

public function show()
{
  $this->show = true;
}

delete this method

public function render() {
 return view('livewire.modal');
}

Now we are going to use this modal as our base controller to create reusable modal.

Before that make a modal.blade.php in views\components\modal.blade.php, and add below code:

<div
    x-data="{ show: @entangle($attributes->wire('model')).defer }"
    x-show="show"
    x-on:keydown.escape.window="show = false"
    class="fixed inset-0 overflow-y-auto px-4 py-6 md:py-24 sm:px-0 z-40"
>
    <div class="fixed inset-0 transform" x-on:click="show = false">
        <div x-show="show" class="absolute inset-0 bg-gray-500 opacity-75"></div>
    </div>
    <div x-show="show" class="bg-white rounded-lg overflow-hidden transform sm:w-full sm:mx-auto sm:mx-auto
        max-w-lg">
        {{ $slot }}
    </div>
</div>

Create another file to create a modal that inherits the property and method of Modal.php.

php artisan make:livewire WelcomeModal

It will create two files as CLASS - app/Http/Livewire//WelcomeModal.php VIEW: C:\xampp\htdocs\reusable-modal-ex\resources\views/livewire/welcome-modal.blade.php

Open WelcomeModal.php file and follow these steps

Step 1 - Replace - class WelcomeModal extends Component to class WelcomeModal extends Modal

It will now extend all the properties and methods of the Modal class that we have defined in this class.

Step 2 - we will add the mount() method and pass the simple welcome message.

namespace App\Http\Livewire;

public $message = '';

public function mount()
{
  $this->message = 'Welcome to the reusable modal example';
}

Open welcome-modal.blade.php file and add below code

<div>
    <x-modal wire:model="show">
        <div class="flex justify-between items-center border-b p-2 text-md">
            <h6 class="text-md py-1/5 text-gray-900 font-100">Example of pikaday datepicker </h6>
            <button type="button" x-on:click="show = false">
                <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 text-red-400" viewBox="0 0 20 20" fill="currentColor">
                    <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd" />
                </svg>
            </button>
        </div>
        <div class="p-4">
            {{ $message }}
        </div>
    </x-modal>
</div>

Our Modal is now created and ready for use. :grinning:

Open any blade file where you want to use/open the modal. I am using it in the dashboard.blade.php file.

<button type="button"
        x-data="{}" x-on:click="window.livewire.emitTo('welcome-modal', 'show')"
        class="inline-flex content-end px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
        <span>
            <svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5 text-white" viewBox="0 0 20 20" fill="currentColor">
                <path fill-rule="evenodd"
                    d="M10 5a1 1 0 011 1v3h3a1 1 0 110 2h-3v3a1 1 0 11-2 0v-3H6a1 1 0 110-2h3V6a1 1 0 011-1z"
                    clip-rule="evenodd"
                />
            </svg>
        </span>Click to Open Modal
    </button>

and add livewire component after the end of the button

<livewire:welcome-modal />

Hurray!! We have created a reusable modal and used it in the laravel and livewire app.

Note:

  1. In button you can see x-on:click="window.livewire.emitTo('welcome-modal', 'show')" this code, it is very import to call modal, and show value which will set true/false.
  2. <livewire:welcome-modal /> and this is used to register your component in the dashboard.

Thank you for reading!!