Home > Modal

Modal

In this example we demostrate how you can achive a modal using hotwire.

The idea is to replace a turbo frame with modal content. The turbo frame need to be acessible by all yielded content so we can place it at the layout before closing the </body>

# app/views/layouts/application.html.erb

<!DOCTYPE html>
<html>
  <head>
  </head>
  <body>
    <main>
      <%= yield %>
    </main>
    <%= turbo_frame_tag :modal %>
  </body>
</html>

Now whenever we want to display the modal, we target this frame with the request.

  <%= link_to "Open modal", new_product_path, data: { turbo_frame: :modal }  %>

This request will replace modal frame with content from it's response. The response it wrapped on a frame matching the id of the frame to replace modal

# app/products/new.html.erb

<%= turbo_frame_tag :modal do %>
  <div class="fixed inset-0 z-50 p-2" role="dialog" aria-modal="true">
    <div class="fixed inset-0 transition-opacity bg-gray-400 bg-opacity-75" aria-hidden="true"></div>
    <div class="relative flex items-center justify-center h-full">
      <div class="w-full max-w-sm max-h-screen px-5 py-3 overflow-auto bg-white rounded-lg md:max-w-lg">
        <%# modal content %>
      </div>
    </div>
  </div>
<% end %>

A simple solution to close this modal is to link back to products_path using data-turb-frame="_top". Later in this example we will look how can close the modal using stimulus when you click outside the modal

<%= link_to "Close", products_path, data: { turbo_frame: "_top" } %>