Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

jmacdiarmid's avatar

How to render show modal in a Livewire component?

I have 2 livewire components. The first is a datatable that renders a paginated index of all records. The second component is used to create, edit and delete. I'm not sure what the best practice is, but I was thinking I should combine them both into one component.

Also, I would like to have the usual three buttons in the last column of the table index but I'm having trouble finding an example for how the view modal is rendered. The current modals are opened using the showModal = true. Do I need to have a showModal for each modal (showCreateModal, showViewModal, etc)

Suggestions?

0 likes
4 replies
prospero's avatar

When I do that, generally have 2 components like you. One for the list and the other for create/edit. The deletion process I do it in the one. Different like others, I prefer use Bootstrap JS calls for open/close modals...I learned that way and remain use it ;) I'm going to share my way and help you with others like buttons for actions

<table>
  <thead>
     <tr>
         //.......
         <th colspan="2">Actions</th>
     </tr>
  </thead>
  <tbody>
  @foreach($data as $item)
    <tr>
      //............
       <td>
		  <button wire:click="selectedItem({{$item->id}}, 'update')">
          <button wire:click="selectedItem({{$item->id}}, 'delete')">
       <td>
    </tr>
  @endforeach
  </tbody>
</table>
//................
     // modal for create/edit
<div class="modal fade" id="formModal" tabindex="-1" aria-labelledby="formModalLabel" aria-hidden="true">
     <div class="modal-dialog">		
        <div class="modal-content">
           <div class="modal-header box-shadow-1" style="text-shadow: 1px 1px 2px #7DA0B1">
               <h5 class="modal-title" id="formModalLabel">@if(!selectedItem) {{ __('Create') }} @else {{ __('Edit') }} @endif</h5>
               <button type="button" class="close" style="background-color: #c9c9c9" aria-label="{{ __('Close') }}">
               	<span aria-hidden="true"><strong>&times;</strong></span>
               </button>
           </div>
      <div class="modal-body">
           @livewire('form-component')
      </div>
    </div>
   </div>
 </div>

// modal for delete
<div class="modal fade" id="deleteModal" tabindex="-1" aria-labelledby="deleteModalLabel" aria-hidden="true">
   <div class="modal-dialog">
      <div class="modal-content">
         <div class="modal-header box-shadow-1" style="text-shadow: 1px 1px 2px #7DA0B1">
              <h5 class="modal-title" id="deleteModalLabel">{{ __('Delete') }}</h5>
              <button type="button" class="close" style="background-color: #c9c9c9" wire:click="closeDeleteModal" aria-label="{{ __('Close') }}">
                   <span aria-hidden="true"><strong>&times;</strong></span>
              </button>
         </div>
        <div class="modal-body">
           <h3>{{ __('Are you sure?') }}</h3>
         </div>
         <div class="modal-footer">
             <button type="button" class="btn btn-secondary" wire:click="closeDeleteModal">{{ __('Cancel') }}</button>
             <button type="button" class="btn btn-primary" wire:click="destroy" wire:loading.attr="disabled">{{ __('Yes') }}</button>
         </div>
      </div>
    </div>
</div>

//...........
@section('custom_scripts')
     window.addEventListener('openFormModal', event => {
            $("#formModal").modal('show');
        })

        window.addEventListener('closeFormModal', event => {
            $("#formModal").modal('hide');
        })

        window.addEventListener('openDeleteModal', event => {
            $("#deleteModal").modal('show');
        })

        window.addEventListener('closeDeleteModal', event => {
            $("#deleteModal").modal('hide');
        })
@endsection


There you have all the blade for the first component, in this backend for the 2 method create/edit and delete

public $selectedItem;
//.....

public function selectedItem($modelId, $action)
{
    $this->selectedItem = $modelId;
    if($action == 'update') {
       $this->emit('selectedItem', $this->selectedItem);  //emit to the form component to load the model
       $this->dispatchBrowserEvent('openFormModal')
    }
    elseif($action == 'delete') {
       $this->dispatchBrowserEvent('openDeleteModal');
    }
}

public function destroy()
{
    Model::destroy($this->selectedItem);
}

For the form component (create/edit) is the usual form component but first this receive the emited event from parent to load the model to be updated. Otherwise the modal is opened to create new modal. Hope this help you I little. Greetings

1 like
jmacdiarmid's avatar

Thank you - This looks good. I knew there was something I forgot to mention. Fortunately or (Unfortunately if subscribe to the Bootstrap Koolaid) :) I'm using Tailwindcss and Alpine.js.

prospero's avatar

Well I'm sorry, really hope you find best answer ;)

2 likes

Please or to participate in this conversation.