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 } endNow 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