Handle simple remote modal dialogs in rails applications

I will show you how to handle simple remote modal dialog rendering in rails apps.

Sometimes we do not want to write big javascript applications to have working remote modals in our rails applications. And rendering modals on the client is to bit of a hassle? Why not let the server (fastest html renderer in town) respond with complete dialogs?

Iam using Bootstrap Modals for this example. But it will work for any JS modal library.

Step 1 – Add a new modal layout.

<!-- app/views/layouts/modal.html.erb -->
<div class="modal fade" tabindex="-1" role="dialog">
  <div class="modal-dialog">
    <div class="modal-content">
      <%= yield %>
    </div><!-- /.modal-content -->
  </div><!-- /.modal-dialog -->
</div><!-- /.modal -->

We also need to define a place where the dialogs will be rendered. Add the following to the application layout file.

<!-- app/views/layouts/application.html.erb -->
<div id="modal-holder"></div>

Step 2 – Add modal javascript

This will enable links with data-behavior=”modal” attribute to be rendered in modal windows.

$ ->
  modal_holder_selector = "#modal-holder"

  $(document).on "click", "[data-behavior='modal']", ->
    location = $(this).attr("href")
    $.get location, (data)->

  $(document).on "ajax:success", "[data-behavior='modal-form']", (event, data, status, xhr) ->
    # make sure this event is observered by document and not by dom node itself.
    url = xhr.getResponseHeader("Location")
    # Navigates to given location header in http response or closes the modal handler.
    if url
      window.location = url
      # FUTURE TODO: make sure only the modal which was called last will be destroyed.

Step 3 – Modify controller action

Now change the render layout for the controller action like so:

class ApplesController < ApplicationController
  def new
    @apples = Apple
    render layout: 'modal'

Step 4 – Use it

<%= link_to 'Create apple', new_apple_path, data: { behavior: 'modal' } %>

Please make sure the rendered form will have a data-behavior=”modal-form” attribute to successfully close the dialog after valid ajax response.