DeveloperBreeze

Managing Modals with Livewire and JavaScript

When using Livewire, it's common to encounter issues with JavaScript-based interactions, such as modals, due to Livewire's re-rendering of the DOM. This tutorial will guide you through using Livewire's event system to handle modals more effectively.

Prerequisites

  • Basic understanding of Livewire and JavaScript
  • A Laravel project with Livewire installed

Objective

We'll create a system to open and close modals using Livewire and JavaScript by dispatching custom events.

Step 1: Setting Up the Livewire Component

Create a Livewire component, or use an existing one where you want to manage modals.

Component Class

Add methods to dispatch custom browser events when buttons are clicked:

<?php

namespace App\Http\Livewire;

use Livewire\Component;

class ModalManager extends Component
{
    public function openUserProfileModal()
    {
        $this->dispatchBrowserEvent('open-modal', ['modalId' => 'user-profile-modal']);
    }

    public function openSettingsModal()
    {
        $this->dispatchBrowserEvent('open-modal', ['modalId' => 'settings-modal']);
    }

    public function openNotificationsModal()
    {
        $this->dispatchBrowserEvent('open-modal', ['modalId' => 'notifications-modal']);
    }

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

Step 2: Updating the Blade View

Modify your Livewire component's Blade view to call the methods defined in the component class.

Blade Template

<!-- Button for User Profile Modal -->
<div class="mt-7">
    <a href="javascript:;" wire:click.prevent="openUserProfileModal" class="font-industry-medium text-[16px] text-[#284E7B] underline decoration-solid decoration-[#284E7B]">+ Open User Profile</a>
</div>

<!-- Button for Settings Modal -->
<div class="mt-7">
    <a href="javascript:;" wire:click.prevent="openSettingsModal" class="font-industry-medium text-[16px] text-[#284E7B] underline decoration-solid decoration-[#284E7B]">+ Open Settings</a>
</div>

<!-- Button for Notifications Modal -->
<div class="mt-7">
    <a href="javascript:;" wire:click.prevent="openNotificationsModal" class="font-industry-medium text-[16px] text-[#284E7B] underline decoration-solid decoration-[#284E7B]">+ Open Notifications</a>
</div>

<!-- Modals -->
<div id="user-profile-modal" class="modal hidden"> <!-- User Profile Modal content here --> </div>
<div id="settings-modal" class="modal hidden"> <!-- Settings Modal content here --> </div>
<div id="notifications-modal" class="modal hidden"> <!-- Notifications Modal content here --> </div>

Step 3: Adding JavaScript for Event Listening

Add a script to listen for the custom events emitted by Livewire and open the modals accordingly.

JavaScript

<script>
    document.addEventListener('DOMContentLoaded', function () {
        // Listen for the custom 'open-modal' event
        window.addEventListener('open-modal', event => {
            const modalId = event.detail.modalId;
            const modalElement = document.getElementById(modalId);
            if (modalElement) {
                modalElement.classList.remove('hidden');
            }
        });

        // Close modal logic
        document.querySelectorAll('[data-modal-hide]').forEach(button => {
            button.addEventListener('click', function () {
                const modalId = this.getAttribute('data-modal-hide');
                const modalElement = document.getElementById(modalId);
                if (modalElement) {
                    modalElement.classList.add('hidden');
                }
            });
        });
    });
</script>

Explanation

  • Custom Events: We use Livewire's dispatchBrowserEvent to emit a custom event open-modal with the modalId as a parameter.
  • JavaScript Listener: A listener is set up for the open-modal event to open the specified modal by removing the hidden class. This ensures that JavaScript functions properly even after Livewire re-renders parts of the page.
  • Close Logic: We add listeners for buttons that hide the modals, ensuring a full modal lifecycle.

Conclusion

By using Livewire's event dispatching capabilities in combination with JavaScript, you can manage modals effectively even when Livewire re-renders the DOM. This approach provides a seamless user experience for modal interactions.

Continue Reading

Discover more amazing content handpicked just for you

Tutorial

Livewire Cheat Sheet: PHP & JavaScript Tips

  • Use $refresh to reload or refresh a component in PHP.
   protected $listeners = ['refreshComponent' => '$refresh'];

Oct 24, 2024
Read More
Tutorial
javascript php

Managing WYSIWYG Editors with Livewire: A Step-by-Step Guide

    namespace App\Http\Livewire;

    use Livewire\Component;

    class EditorComponent extends Component
    {
        public $content = '';

        protected $listeners = ['updateContent'];

        public function updateContent($wireId, $newContent)
        {
            $this->content = $newContent;
        }

        public function render()
        {
            return view('livewire.editor-component');
        }
    }

Here, we’ve defined a content property to store the editor’s content. The updateContent method listens for updates from the front-end and sets the content accordingly.

Aug 14, 2024
Read More
Tutorial
javascript php

Implementing Real-Time Search with Livewire in Laravel

  • Basic understanding of Laravel and Livewire
  • A Laravel project with Livewire installed

We'll create a real-time search form that filters and displays results as the user types in the search input field.

Aug 14, 2024
Read More
Tutorial
php

Dynamically Updating Form Fields with Livewire in Laravel

php artisan make:livewire DynamicForm

Open the newly created DynamicForm.php file and set up the properties and methods to manage the form fields:

Aug 14, 2024
Read More
Code
javascript

Password Toggle

No preview available for this content.

Jan 26, 2024
Read More
Code
javascript

Dark Mode Toggle

No preview available for this content.

Jan 26, 2024
Read More

Discussion 0

Please sign in to join the discussion.

No comments yet. Start the discussion!