Monday, December 2, 2013

Rails, Ajax Requests, and Playing Nicely with respond_to do |format|

So this morning I'm working on making a highly interactive dialog for +Rentables. The dialog is initially loaded via ajax using the very familiar respond_to block where render_ajax_dialog is a helper specific to my project.
respond_to do |format|
  format.html {}
  format.js { render_ajax_dialog }
end
Now when the user clicks certain buttons on the dialog, I want to refresh the dialog from the server (i.e. Ajax) without reloading the underlying page and without the updating controller having to know anything about the dialog - basically the blind interacting with the blind.
Pop quiz: How do the blind interact in the stateless hyper text transfer protocol world?
My solution is to pass a parameter to the updating controller (:redisplay) with the URL to the action which renders the dialog. It seems a bit messy, right? Maybe someone reading this has a better idea.
class DialogLoadingController < ApplicationController
  def show
    # load some foo

    respond_to do |format|
      format.html
      format.js { render_ajax_dialog }
    end
  end
end


class UpdatingThingsController < ApplicationController
  def update
    # update some foo

    respond_to do |format|
      format.html { redirect_to pop_return_to_or(foo_path) }
      format.js { 
        if (redisplay = params[:redisplay])
          show_dialog_url = ensure_format_js(redisplay)
          render :js => "$.ajax({url: '#{show_dialog_url}', cache: false});"
        end
      }
    end
  end


  private

  # In order for +respond_to+ to pick JS we need to ensure the URL
  # includes '.js'. The first call will not but subsequent calls will.
  #   ensure_format_js('/path/to/foo?are_you_awesome=true')
  #   # => /path/to/foo.js?are_you_awesome=true
  #
  #   ensure_format_js('/path/to/foo.js?are_you_awesome=true')
  #   # => /path/to/foo.js?are_you_awesome=true
  #
  # @param [String] url the redisplay URL
  # @return [String] Url with format .js specified
  def ensure_format_js(url)
    return nil unless url

    # split off query string, if any
    url = url.split '?'

    # check if JS specified
    if url.first.match(/.*\.js$/)
      # JS specified, re-join URL and query
      url.join('?')
    else
      # add JS and re-join
      url.first + '.js?' + url.last
    end
  end
end

1 comment:

  1. Our Gujarat Escorts Service Agency are tailored and structured for Escorts contact number in Goa those who are experiencing a Gujarat Housewife Escorts agency pitiable plight of the utmost sensual frustration in their lives and searching for something new to renovate and repair it.Model Call Girls in Agra Whosoever has opted for our Indian Escorts contact number in Indore, started admiring not only our beauty but also Escorts contact number in Haridwar the way with which we serve him in the bed.

    ReplyDelete