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